From 3edd2fa811c9d472d6a1281e000e72bfa4f3dc4f Mon Sep 17 00:00:00 2001 From: Alex Barnsley <8069294+alexbarnsley@users.noreply.github.com> Date: Fri, 27 Sep 2024 10:29:16 +0100 Subject: [PATCH] refactor: remove fortify & nova integration (#626) --- README.md | 2 - composer.json | 16 +- composer.lock | 1109 +---------------- config/fortify.php | 183 --- resources/tailwind.config.js | 1 - .../views/auth/confirm-password.blade.php | 1 - .../views/auth/forgot-password.blade.php | 41 - resources/views/auth/login.blade.php | 89 -- resources/views/auth/register-form.blade.php | 108 -- resources/views/auth/register.blade.php | 19 - .../views/auth/reset-password-form.blade.php | 66 - resources/views/auth/reset-password.blade.php | 13 - .../views/auth/two-factor-challenge.blade.php | 16 - .../views/auth/two-factor/form.blade.php | 33 - .../auth/two-factor/recovery-form.blade.php | 30 - resources/views/auth/verify-email.blade.php | 11 - .../views/profile/delete-user-form.blade.php | 95 -- .../views/profile/export-user-data.blade.php | 18 - .../profile/feedback-thank-you.blade.php | 20 - ...gout-other-browser-sessions-form.blade.php | 185 --- .../two-factor-authentication-form.blade.php | 167 --- .../profile/update-password-form.blade.php | 72 -- .../update-profile-information-form.blade.php | 16 - .../update-profile-photo-form.blade.php | 15 - .../profile/update-timezone-form.blade.php | 24 - .../Components/Concerns/InteractsWithUser.php | 2 +- src/{Fortify => Blog}/Contracts/UserRole.php | 2 +- .../EnforceTwoFactorAuthentication.php | 2 +- .../Concerns/HasLocalizedTimestamps.php | 2 +- src/Blog/Models/User.php | 49 +- src/Fortify/Actions/AuthenticateUser.php | 66 - src/Fortify/Actions/CreateNewUser.php | 119 -- src/Fortify/Actions/DeleteUser.php | 15 - .../Actions/EnableTwoFactorAuthentication.php | 49 - ...nerateTwoFactorAuthenticationSecretKey.php | 39 - .../Actions/PasswordValidationRules.php | 41 - src/Fortify/Actions/ResetUserPassword.php | 38 - src/Fortify/Actions/SubscribeToNewsletter.php | 29 - src/Fortify/Actions/UpdateUserPassword.php | 43 - .../Actions/UpdateUserProfileInformation.php | 70 -- .../Components/Concerns/ValidatesPassword.php | 55 - src/Fortify/Components/DeleteUserForm.php | 98 -- src/Fortify/Components/ExportUserData.php | 54 - .../FooterEmailSubscriptionForm.php | 48 - .../LogoutOtherBrowserSessionsForm.php | 100 -- src/Fortify/Components/RegisterForm.php | 127 -- src/Fortify/Components/ResetPasswordForm.php | 47 - .../TwoFactorAuthenticationForm.php | 192 --- src/Fortify/Components/UpdatePasswordForm.php | 70 -- .../UpdateProfileInformationForm.php | 67 - .../Components/UpdateProfilePhotoForm.php | 70 -- src/Fortify/Components/UpdateTimezoneForm.php | 54 - src/Fortify/Components/VerifyEmail.php | 42 - .../Console/Commands/CreateUserCommand.php | 90 -- .../Console/Commands/RunPlaybookCommand.php | 147 --- .../Playbooks/AccessControlPlaybook.php | 53 - .../Console/Playbooks/DemoPlaybook.php | 24 - .../Playbooks/ManagementUserPlaybook.php | 32 - src/Fortify/Console/Playbooks/Playbook.php | 45 - .../Console/Playbooks/PlaybookDefinition.php | 44 - src/Fortify/Contracts/DeleteUser.php | 17 - ...orAuthenticatedPasswordResetController.php | 62 - .../TwoFactorResetPasswordRequest.php | 62 - ...FailedPasswordResetLinkRequestResponse.php | 31 - ...essfulPasswordResetLinkRequestResponse.php | 27 - src/Fortify/Mail/SendFeedback.php | 29 - src/Fortify/Models.php | 28 - src/Fortify/Models/Concerns/HasPhoto.php | 28 - src/Fortify/Models/Permission.php | 60 - src/Fortify/Models/User.php | 19 - .../Models/UserWithoutVerification.php | 78 -- src/Fortify/Notifications/AccountCreated.php | 48 - .../Nova/Fields/PermissionBooleanGroup.php | 51 - src/Fortify/Nova/Fields/RoleBooleanGroup.php | 28 - src/Fortify/Nova/Permission.php | 49 - src/Fortify/Nova/Role.php | 34 - .../Concerns/HasDefaultPolicyRules.php | 48 - src/Fortify/Policies/PermissionPolicy.php | 53 - src/Fortify/Policies/Policy.php | 14 - src/Fortify/Policies/RolePolicy.php | 53 - src/Fortify/Policies/UserPolicy.php | 28 - .../FailedTwoFactorLoginResponse.php | 38 - src/Fortify/Responses/RegisterResponse.php | 47 - .../Responses/TwoFactorLoginResponse.php | 27 - src/Fortify/Rules/Concerns/BaseRule.php | 12 - .../Rules/Concerns/ReservedUsername.php | 20 - src/Fortify/Rules/DisplayNameCharacters.php | 97 -- src/Fortify/Rules/OneLetter.php | 36 - src/Fortify/Rules/OneTimePassword.php | 32 - .../Rules/StartsWithLetterOrNumber.php | 36 - src/Fortify/Rules/Username.php | 198 --- src/Fortify/Support/Enums/Constants.php | 16 - src/Fortify/Support/Enums/UserRole.php | 20 - .../Support/Services/PermissionMapping.php | 56 - .../Support/Services/PermissionRegistrar.php | 41 - src/Hermes/Components/ManageNotifications.php | 2 +- src/Hermes/Models/DatabaseNotification.php | 2 +- src/Providers/FortifyServiceProvider.php | 292 ----- src/Providers/FoundationServiceProvider.php | 5 - src/Providers/NovaServiceProvider.php | 114 -- tests/Blog/TestCase.php | 12 +- .../Fortify/Actions/AuthenticateUserTest.php | 174 --- tests/Fortify/Actions/CreateNewUserTest.php | 312 ----- tests/Fortify/Actions/DeleteUserTest.php | 21 - .../EnableTwoFactorAuthenticationTest.php | 18 - ...teTwoFactorAuthenticationSecretKeyTest.php | 11 - .../Fortify/Actions/ResetUserPasswordTest.php | 71 -- .../Actions/SubscribeToNewsletterTest.php | 47 - .../Actions/UpdateUserPasswordTest.php | 75 -- .../UpdateUserProfileInformationTest.php | 127 -- .../Fortify/Components/DeleteUserFormTest.php | 127 -- .../Fortify/Components/ExportUserDataTest.php | 50 - .../FooterEmailSubscriptionFormTest.php | 70 -- .../LogoutOtherBrowserSessionsFormTest.php | 112 -- tests/Fortify/Components/RegisterFormTest.php | 106 -- .../Components/ResetPasswordFormTest.php | 38 - .../TwoFactorAuthenticationFormTest.php | 122 -- .../Components/UpdatePasswordFormTest.php | 193 --- .../UpdateProfileInformationFormTest.php | 18 - .../Components/UpdateProfilePhotoFormTest.php | 92 -- .../Components/UpdateTimezoneFormTest.php | 88 -- tests/Fortify/Components/VerifyEmailTest.php | 34 - ...thenticatedPasswordResetControllerTest.php | 149 --- .../TwoFactorResetPasswordRequestTest.php | 151 --- ...edPasswordResetLinkRequestResponseTest.php | 26 - ...ulPasswordResetLinkRequestResponseTest.php | 29 - tests/Fortify/Mail/SendFeedbackTest.php | 26 - tests/Fortify/MediaUser.php | 29 - .../Concerns/HasLocalizedTimestampsTest.php | 74 -- .../Fortify/Models/Concerns/HasPhotoTest.php | 50 - tests/Fortify/ModelsTest.php | 18 - .../FailedTwoFactorLoginResponseTest.php | 51 - .../Responses/RegisterResponseTest.php | 117 -- .../Responses/TwoFactorLoginResponseTest.php | 70 -- .../Rules/Concerns/ReservedUsernameTest.php | 37 - .../Rules/DisplayNameCharactersTest.php | 102 -- tests/Fortify/Rules/OneLetterTest.php | 30 - tests/Fortify/Rules/OneTimePasswordTest.php | 17 - .../Rules/StartsWithLetterOrNumberTest.php | 30 - tests/Fortify/Rules/UsernameTest.php | 134 -- tests/Fortify/UserWithNotifications.php | 28 - tests/Fortify/UserWithoutVerification.php | 18 - tests/Fortify/stubs/TestUser.php | 52 - tests/Helpers.php | 2 +- tests/Pest.php | 6 +- tests/Rules/TestCase.php | 56 + tests/Rules/UniqueCaseInsensitiveTest.php | 7 +- tests/TestCase.php | 7 +- usage/fortify.md | 189 --- 149 files changed, 162 insertions(+), 9574 deletions(-) delete mode 100644 config/fortify.php delete mode 100644 resources/views/auth/confirm-password.blade.php delete mode 100644 resources/views/auth/forgot-password.blade.php delete mode 100644 resources/views/auth/login.blade.php delete mode 100644 resources/views/auth/register-form.blade.php delete mode 100644 resources/views/auth/register.blade.php delete mode 100644 resources/views/auth/reset-password-form.blade.php delete mode 100644 resources/views/auth/reset-password.blade.php delete mode 100644 resources/views/auth/two-factor-challenge.blade.php delete mode 100644 resources/views/auth/two-factor/form.blade.php delete mode 100644 resources/views/auth/two-factor/recovery-form.blade.php delete mode 100644 resources/views/auth/verify-email.blade.php delete mode 100644 resources/views/profile/delete-user-form.blade.php delete mode 100644 resources/views/profile/export-user-data.blade.php delete mode 100644 resources/views/profile/feedback-thank-you.blade.php delete mode 100644 resources/views/profile/logout-other-browser-sessions-form.blade.php delete mode 100644 resources/views/profile/two-factor-authentication-form.blade.php delete mode 100644 resources/views/profile/update-password-form.blade.php delete mode 100644 resources/views/profile/update-profile-information-form.blade.php delete mode 100644 resources/views/profile/update-profile-photo-form.blade.php delete mode 100644 resources/views/profile/update-timezone-form.blade.php rename src/{Fortify => Blog}/Components/Concerns/InteractsWithUser.php (82%) rename src/{Fortify => Blog}/Contracts/UserRole.php (65%) rename src/{Fortify => Blog}/Http/Middleware/EnforceTwoFactorAuthentication.php (91%) rename src/{Fortify => Blog}/Models/Concerns/HasLocalizedTimestamps.php (91%) delete mode 100644 src/Fortify/Actions/AuthenticateUser.php delete mode 100644 src/Fortify/Actions/CreateNewUser.php delete mode 100644 src/Fortify/Actions/DeleteUser.php delete mode 100644 src/Fortify/Actions/EnableTwoFactorAuthentication.php delete mode 100644 src/Fortify/Actions/GenerateTwoFactorAuthenticationSecretKey.php delete mode 100644 src/Fortify/Actions/PasswordValidationRules.php delete mode 100644 src/Fortify/Actions/ResetUserPassword.php delete mode 100644 src/Fortify/Actions/SubscribeToNewsletter.php delete mode 100644 src/Fortify/Actions/UpdateUserPassword.php delete mode 100644 src/Fortify/Actions/UpdateUserProfileInformation.php delete mode 100644 src/Fortify/Components/Concerns/ValidatesPassword.php delete mode 100644 src/Fortify/Components/DeleteUserForm.php delete mode 100644 src/Fortify/Components/ExportUserData.php delete mode 100644 src/Fortify/Components/FooterEmailSubscriptionForm.php delete mode 100644 src/Fortify/Components/LogoutOtherBrowserSessionsForm.php delete mode 100644 src/Fortify/Components/RegisterForm.php delete mode 100644 src/Fortify/Components/ResetPasswordForm.php delete mode 100644 src/Fortify/Components/TwoFactorAuthenticationForm.php delete mode 100644 src/Fortify/Components/UpdatePasswordForm.php delete mode 100644 src/Fortify/Components/UpdateProfileInformationForm.php delete mode 100644 src/Fortify/Components/UpdateProfilePhotoForm.php delete mode 100644 src/Fortify/Components/UpdateTimezoneForm.php delete mode 100644 src/Fortify/Components/VerifyEmail.php delete mode 100644 src/Fortify/Console/Commands/CreateUserCommand.php delete mode 100644 src/Fortify/Console/Commands/RunPlaybookCommand.php delete mode 100644 src/Fortify/Console/Playbooks/AccessControlPlaybook.php delete mode 100644 src/Fortify/Console/Playbooks/DemoPlaybook.php delete mode 100644 src/Fortify/Console/Playbooks/ManagementUserPlaybook.php delete mode 100644 src/Fortify/Console/Playbooks/Playbook.php delete mode 100644 src/Fortify/Console/Playbooks/PlaybookDefinition.php delete mode 100644 src/Fortify/Contracts/DeleteUser.php delete mode 100644 src/Fortify/Http/Controllers/TwoFactorAuthenticatedPasswordResetController.php delete mode 100644 src/Fortify/Http/Requests/TwoFactorResetPasswordRequest.php delete mode 100644 src/Fortify/Http/Responses/FailedPasswordResetLinkRequestResponse.php delete mode 100644 src/Fortify/Http/Responses/SuccessfulPasswordResetLinkRequestResponse.php delete mode 100644 src/Fortify/Mail/SendFeedback.php delete mode 100644 src/Fortify/Models.php delete mode 100644 src/Fortify/Models/Concerns/HasPhoto.php delete mode 100644 src/Fortify/Models/Permission.php delete mode 100644 src/Fortify/Models/User.php delete mode 100644 src/Fortify/Models/UserWithoutVerification.php delete mode 100644 src/Fortify/Notifications/AccountCreated.php delete mode 100644 src/Fortify/Nova/Fields/PermissionBooleanGroup.php delete mode 100644 src/Fortify/Nova/Fields/RoleBooleanGroup.php delete mode 100644 src/Fortify/Nova/Permission.php delete mode 100644 src/Fortify/Nova/Role.php delete mode 100644 src/Fortify/Policies/Concerns/HasDefaultPolicyRules.php delete mode 100644 src/Fortify/Policies/PermissionPolicy.php delete mode 100644 src/Fortify/Policies/Policy.php delete mode 100644 src/Fortify/Policies/RolePolicy.php delete mode 100644 src/Fortify/Policies/UserPolicy.php delete mode 100644 src/Fortify/Responses/FailedTwoFactorLoginResponse.php delete mode 100644 src/Fortify/Responses/RegisterResponse.php delete mode 100644 src/Fortify/Responses/TwoFactorLoginResponse.php delete mode 100644 src/Fortify/Rules/Concerns/BaseRule.php delete mode 100644 src/Fortify/Rules/Concerns/ReservedUsername.php delete mode 100644 src/Fortify/Rules/DisplayNameCharacters.php delete mode 100644 src/Fortify/Rules/OneLetter.php delete mode 100644 src/Fortify/Rules/OneTimePassword.php delete mode 100644 src/Fortify/Rules/StartsWithLetterOrNumber.php delete mode 100644 src/Fortify/Rules/Username.php delete mode 100644 src/Fortify/Support/Enums/Constants.php delete mode 100644 src/Fortify/Support/Enums/UserRole.php delete mode 100644 src/Fortify/Support/Services/PermissionMapping.php delete mode 100644 src/Fortify/Support/Services/PermissionRegistrar.php delete mode 100644 src/Providers/FortifyServiceProvider.php delete mode 100644 src/Providers/NovaServiceProvider.php delete mode 100644 tests/Fortify/Actions/AuthenticateUserTest.php delete mode 100644 tests/Fortify/Actions/CreateNewUserTest.php delete mode 100644 tests/Fortify/Actions/DeleteUserTest.php delete mode 100644 tests/Fortify/Actions/EnableTwoFactorAuthenticationTest.php delete mode 100644 tests/Fortify/Actions/GenerateTwoFactorAuthenticationSecretKeyTest.php delete mode 100644 tests/Fortify/Actions/ResetUserPasswordTest.php delete mode 100644 tests/Fortify/Actions/SubscribeToNewsletterTest.php delete mode 100644 tests/Fortify/Actions/UpdateUserPasswordTest.php delete mode 100644 tests/Fortify/Actions/UpdateUserProfileInformationTest.php delete mode 100644 tests/Fortify/Components/DeleteUserFormTest.php delete mode 100644 tests/Fortify/Components/ExportUserDataTest.php delete mode 100644 tests/Fortify/Components/FooterEmailSubscriptionFormTest.php delete mode 100644 tests/Fortify/Components/LogoutOtherBrowserSessionsFormTest.php delete mode 100644 tests/Fortify/Components/RegisterFormTest.php delete mode 100644 tests/Fortify/Components/ResetPasswordFormTest.php delete mode 100644 tests/Fortify/Components/TwoFactorAuthenticationFormTest.php delete mode 100644 tests/Fortify/Components/UpdatePasswordFormTest.php delete mode 100644 tests/Fortify/Components/UpdateProfileInformationFormTest.php delete mode 100644 tests/Fortify/Components/UpdateProfilePhotoFormTest.php delete mode 100644 tests/Fortify/Components/UpdateTimezoneFormTest.php delete mode 100644 tests/Fortify/Components/VerifyEmailTest.php delete mode 100644 tests/Fortify/Http/Controllers/TwoFactorAuthenticatedPasswordResetControllerTest.php delete mode 100644 tests/Fortify/Http/Requests/TwoFactorResetPasswordRequestTest.php delete mode 100644 tests/Fortify/Http/Responses/FailedPasswordResetLinkRequestResponseTest.php delete mode 100644 tests/Fortify/Http/Responses/SuccessfulPasswordResetLinkRequestResponseTest.php delete mode 100644 tests/Fortify/Mail/SendFeedbackTest.php delete mode 100644 tests/Fortify/MediaUser.php delete mode 100644 tests/Fortify/Models/Concerns/HasLocalizedTimestampsTest.php delete mode 100644 tests/Fortify/Models/Concerns/HasPhotoTest.php delete mode 100644 tests/Fortify/ModelsTest.php delete mode 100644 tests/Fortify/Responses/FailedTwoFactorLoginResponseTest.php delete mode 100644 tests/Fortify/Responses/RegisterResponseTest.php delete mode 100644 tests/Fortify/Responses/TwoFactorLoginResponseTest.php delete mode 100644 tests/Fortify/Rules/Concerns/ReservedUsernameTest.php delete mode 100644 tests/Fortify/Rules/DisplayNameCharactersTest.php delete mode 100644 tests/Fortify/Rules/OneLetterTest.php delete mode 100644 tests/Fortify/Rules/OneTimePasswordTest.php delete mode 100644 tests/Fortify/Rules/StartsWithLetterOrNumberTest.php delete mode 100644 tests/Fortify/Rules/UsernameTest.php delete mode 100644 tests/Fortify/UserWithNotifications.php delete mode 100644 tests/Fortify/UserWithoutVerification.php delete mode 100644 tests/Fortify/stubs/TestUser.php create mode 100644 tests/Rules/TestCase.php delete mode 100644 usage/fortify.md diff --git a/README.md b/README.md index 2d8b3a0f6..1c8a015bd 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,6 @@ Require with composer: `composer require arkecosystem/foundation` - [CommonMark](/usage/commonmark.md) - [Documentation](/usage/documentation.md) -- [Fortify](/usage/fortify.md) - [Hermes](/usage/hermes.md) - [Stan](/usage/stan.md) - [UI](/usage/ui.md) @@ -34,7 +33,6 @@ Require with composer: `composer require arkecosystem/foundation` ## Examples - [CommonMark](/examples/commonmark.md) -- [Fortify](/examples/fortify.md) - [Hermes](/examples/hermes.md) - [UI](/examples/ui.md) diff --git a/composer.json b/composer.json index 12d57d0b5..5ad8084c6 100644 --- a/composer.json +++ b/composer.json @@ -85,12 +85,6 @@ ] } }, - "repositories": [ - { - "type": "composer", - "url": "https://nova.laravel.com" - } - ], "scripts": { "format": [ "vendor/bin/php-cs-fixer fix" @@ -114,15 +108,7 @@ } }, "require-dev": { - "laravel/nova": "^4.13", "orchestra/testbench": "^8.22", - "spatie/laravel-permission": "^5.10", - "spatie/mailcoach-sdk-php": "^1.4", - "vyuldashev/nova-permission": "^3.2" - }, - "suggest": { - "laravel/nova": "Needed for backend management of data", - "spatie/laravel-permission": "Needed for nova permissions & roles", - "vyuldashev/nova-permission": "Needed for nova permissions & roles" + "spatie/mailcoach-sdk-php": "^1.4" } } diff --git a/composer.lock b/composer.lock index 813c65ae4..67d74df54 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "15ff9f610430ef09133332d0962ad3d4", + "content-hash": "1bd29d563bc2c014d4834e8f3ddd4291", "packages": [ { "name": "bacon/bacon-qr-code", @@ -12603,546 +12603,6 @@ } ], "packages-dev": [ - { - "name": "brick/money", - "version": "0.8.0", - "source": { - "type": "git", - "url": "https://github.com/brick/money.git", - "reference": "b530ab64d7f85fdfd5858cde8c57f2f587c8aab8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/brick/money/zipball/b530ab64d7f85fdfd5858cde8c57f2f587c8aab8", - "reference": "b530ab64d7f85fdfd5858cde8c57f2f587c8aab8", - "shasum": "" - }, - "require": { - "brick/math": "~0.10.1 || ~0.11.0", - "ext-json": "*", - "php": "^8.0" - }, - "require-dev": { - "brick/varexporter": "~0.3.0", - "ext-dom": "*", - "ext-pdo": "*", - "php-coveralls/php-coveralls": "^2.2", - "phpunit/phpunit": "^9.4.3", - "vimeo/psalm": "5.4.0" - }, - "suggest": { - "ext-intl": "Required to format Money objects" - }, - "type": "library", - "autoload": { - "psr-4": { - "Brick\\Money\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Money and currency library", - "keywords": [ - "brick", - "currency", - "money" - ], - "support": { - "issues": "https://github.com/brick/money/issues", - "source": "https://github.com/brick/money/tree/0.8.0" - }, - "funding": [ - { - "url": "https://github.com/BenMorel", - "type": "github" - } - ], - "time": "2023-01-15T23:59:01+00:00" - }, - { - "name": "doctrine/cache", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/cache.git", - "reference": "1ca8f21980e770095a31456042471a57bc4c68fb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb", - "reference": "1ca8f21980e770095a31456042471a57bc4c68fb", - "shasum": "" - }, - "require": { - "php": "~7.1 || ^8.0" - }, - "conflict": { - "doctrine/common": ">2.2,<2.4" - }, - "require-dev": { - "cache/integration-tests": "dev-master", - "doctrine/coding-standard": "^9", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "psr/cache": "^1.0 || ^2.0 || ^3.0", - "symfony/cache": "^4.4 || ^5.4 || ^6", - "symfony/var-exporter": "^4.4 || ^5.4 || ^6" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", - "homepage": "https://www.doctrine-project.org/projects/cache.html", - "keywords": [ - "abstraction", - "apcu", - "cache", - "caching", - "couchdb", - "memcached", - "php", - "redis", - "xcache" - ], - "support": { - "issues": "https://github.com/doctrine/cache/issues", - "source": "https://github.com/doctrine/cache/tree/2.2.0" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache", - "type": "tidelift" - } - ], - "time": "2022-05-20T20:07:39+00:00" - }, - { - "name": "doctrine/dbal", - "version": "3.6.4", - "source": { - "type": "git", - "url": "https://github.com/doctrine/dbal.git", - "reference": "19f0dec95edd6a3c3c5ff1d188ea94c6b7fc903f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/19f0dec95edd6a3c3c5ff1d188ea94c6b7fc903f", - "reference": "19f0dec95edd6a3c3c5ff1d188ea94c6b7fc903f", - "shasum": "" - }, - "require": { - "composer-runtime-api": "^2", - "doctrine/cache": "^1.11|^2.0", - "doctrine/deprecations": "^0.5.3|^1", - "doctrine/event-manager": "^1|^2", - "php": "^7.4 || ^8.0", - "psr/cache": "^1|^2|^3", - "psr/log": "^1|^2|^3" - }, - "require-dev": { - "doctrine/coding-standard": "12.0.0", - "fig/log-test": "^1", - "jetbrains/phpstorm-stubs": "2022.3", - "phpstan/phpstan": "1.10.14", - "phpstan/phpstan-strict-rules": "^1.5", - "phpunit/phpunit": "9.6.7", - "psalm/plugin-phpunit": "0.18.4", - "squizlabs/php_codesniffer": "3.7.2", - "symfony/cache": "^5.4|^6.0", - "symfony/console": "^4.4|^5.4|^6.0", - "vimeo/psalm": "4.30.0" - }, - "suggest": { - "symfony/console": "For helpful console commands such as SQL execution and import of files." - }, - "bin": [ - "bin/doctrine-dbal" - ], - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\DBAL\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - } - ], - "description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.", - "homepage": "https://www.doctrine-project.org/projects/dbal.html", - "keywords": [ - "abstraction", - "database", - "db2", - "dbal", - "mariadb", - "mssql", - "mysql", - "oci8", - "oracle", - "pdo", - "pgsql", - "postgresql", - "queryobject", - "sasql", - "sql", - "sqlite", - "sqlserver", - "sqlsrv" - ], - "support": { - "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.6.4" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdbal", - "type": "tidelift" - } - ], - "time": "2023-06-15T07:40:12+00:00" - }, - { - "name": "doctrine/event-manager", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/event-manager.git", - "reference": "750671534e0241a7c50ea5b43f67e23eb5c96f32" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/event-manager/zipball/750671534e0241a7c50ea5b43f67e23eb5c96f32", - "reference": "750671534e0241a7c50ea5b43f67e23eb5c96f32", - "shasum": "" - }, - "require": { - "php": "^8.1" - }, - "conflict": { - "doctrine/common": "<2.9" - }, - "require-dev": { - "doctrine/coding-standard": "^10", - "phpstan/phpstan": "^1.8.8", - "phpunit/phpunit": "^9.5", - "vimeo/psalm": "^4.28" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - }, - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - } - ], - "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.", - "homepage": "https://www.doctrine-project.org/projects/event-manager.html", - "keywords": [ - "event", - "event dispatcher", - "event manager", - "event system", - "events" - ], - "support": { - "issues": "https://github.com/doctrine/event-manager/issues", - "source": "https://github.com/doctrine/event-manager/tree/2.0.0" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fevent-manager", - "type": "tidelift" - } - ], - "time": "2022-10-12T20:59:15+00:00" - }, - { - "name": "inertiajs/inertia-laravel", - "version": "v0.6.9", - "source": { - "type": "git", - "url": "https://github.com/inertiajs/inertia-laravel.git", - "reference": "b983c6eb2fe7460df6170060cdd7b47b5ef6832a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/inertiajs/inertia-laravel/zipball/b983c6eb2fe7460df6170060cdd7b47b5ef6832a", - "reference": "b983c6eb2fe7460df6170060cdd7b47b5ef6832a", - "shasum": "" - }, - "require": { - "ext-json": "*", - "laravel/framework": "^6.0|^7.0|^8.74|^9.0|^10.0", - "php": "^7.2|~8.0.0|~8.1.0|~8.2.0" - }, - "require-dev": { - "mockery/mockery": "^1.3.3", - "orchestra/testbench": "^4.0|^5.0|^6.4|^7.0|^8.0", - "phpunit/phpunit": "^8.0|^9.5.8", - "roave/security-advisories": "dev-master" - }, - "suggest": { - "ext-pcntl": "Recommended when running the Inertia SSR server via the `inertia:start-ssr` artisan command." - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Inertia\\ServiceProvider" - ] - } - }, - "autoload": { - "files": [ - "./helpers.php" - ], - "psr-4": { - "Inertia\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jonathan Reinink", - "email": "jonathan@reinink.ca", - "homepage": "https://reinink.ca" - } - ], - "description": "The Laravel adapter for Inertia.js.", - "keywords": [ - "inertia", - "laravel" - ], - "support": { - "issues": "https://github.com/inertiajs/inertia-laravel/issues", - "source": "https://github.com/inertiajs/inertia-laravel/tree/v0.6.9" - }, - "funding": [ - { - "url": "https://github.com/reinink", - "type": "github" - } - ], - "time": "2023-01-17T01:02:51+00:00" - }, - { - "name": "laravel/nova", - "version": "4.25.1", - "source": { - "type": "git", - "url": "git@github.com:laravel/nova.git", - "reference": "b7537f667ef4ee6a1c9581995d438a6fe214625b" - }, - "dist": { - "type": "zip", - "url": "https://nova.laravel.com/dist/laravel/nova/laravel-nova-b7537f667ef4ee6a1c9581995d438a6fe214625b-zip-ae794f.zip", - "reference": "b7537f667ef4ee6a1c9581995d438a6fe214625b", - "shasum": "29a7eccd46fd5933fffa7ae45a5e6495b46f702f" - }, - "require": { - "brick/money": "^0.5.0|^0.6.0|^0.7.0|^0.8.0", - "doctrine/dbal": "^2.13.3|^3.1.2", - "ext-json": "*", - "illuminate/support": "^8.83.4|^9.3.1|^10.0", - "inertiajs/inertia-laravel": "^0.4.5|^0.5.2|^0.6.0", - "laravel/ui": "^3.3|^4.0", - "nesbot/carbon": "^2.53.1", - "php": "^7.3|^8.0", - "rap2hpoutre/fast-excel": "^3.2|^4.1|^5.0", - "spatie/once": "^1.1|^2.0|^3.0", - "symfony/console": "^5.4|^6.0", - "symfony/finder": "^5.4|^6.0", - "symfony/polyfill-intl-icu": "^1.22.1", - "symfony/process": "^5.4|^6.0" - }, - "require-dev": { - "laravel/nova-dusk-suite": "8.4.x-dev|9.4.x-dev|10.4.x-dev", - "laravel/pint": "^1.6", - "laravel/scout": "^9.8|^10.0", - "mockery/mockery": "^1.4.4", - "nunomaduro/larastan": "^1.0.1|^2.5.1", - "orchestra/testbench-dusk": "^6.24|^7.21|^8.0", - "phpunit/phpunit": "^9.6|^10.1", - "predis/predis": "^1.1.9|^2.0" - }, - "suggest": { - "ext-intl": "Required to format Currency field" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - }, - "laravel": { - "providers": [ - "Laravel\\Nova\\NovaCoreServiceProvider" - ], - "aliases": { - "Nova": "Laravel\\Nova\\Nova" - } - } - }, - "autoload": { - "psr-4": { - "Laravel\\Nova\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "Laravel\\Nova\\Tests\\": "tests/" - } - }, - "scripts": { - "dusk:prepare": [ - "./vendor/bin/dusk-updater detect --auto-update", - "@php -r \"file_exists('phpunit.dusk.xml') || copy('phpunit.dusk.xml.dist', 'phpunit.dusk.xml'); \"", - "@php -r \"if (file_exists('.env.dusk')) { copy('.env.dusk', 'vendor/laravel/nova-dusk-suite/.env'); } else { copy('.env.dusk.example', 'vendor/laravel/nova-dusk-suite/.env'); }\"", - "./vendor/bin/testbench-dusk package:discover" - ], - "dusk:dev-assets": [ - "TAILWIND_MODE=build npm run dev", - "./vendor/bin/testbench-dusk nova:publish --force" - ], - "dusk:assets": [ - "TAILWIND_MODE=build npm run prod", - "./vendor/bin/testbench-dusk nova:publish --force" - ], - "dusk:test": [ - "./vendor/bin/testbench-dusk package:dusk-purge", - "./vendor/bin/phpunit -c phpunit.dusk.xml" - ], - "test:local": [ - "./vendor/bin/testbench-dusk package:dusk-purge", - "./vendor/bin/phpunit -c phpunit.xml --group local-time,external-network --testdox", - "./vendor/bin/phpunit -c phpunit.dusk.xml --group local-time,external-network --testdox" - ], - "dusk:filter": [ - "./vendor/bin/testbench-dusk package:dusk-purge && ./vendor/bin/phpunit -c phpunit.dusk.xml --filter" - ] - }, - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "A wonderful administration interface for Laravel.", - "keywords": [ - "admin", - "laravel" - ], - "support": { - "source": "https://github.com/laravel/nova/tree/v4.25.1" - }, - "time": "2023-06-06T18:29:19+00:00" - }, { "name": "laravel/tinker", "version": "v2.9.0", @@ -13209,161 +12669,6 @@ }, "time": "2024-01-04T16:10:04+00:00" }, - { - "name": "laravel/ui", - "version": "v4.2.2", - "source": { - "type": "git", - "url": "https://github.com/laravel/ui.git", - "reference": "a58ec468db4a340b33f3426c778784717a2c144b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/ui/zipball/a58ec468db4a340b33f3426c778784717a2c144b", - "reference": "a58ec468db4a340b33f3426c778784717a2c144b", - "shasum": "" - }, - "require": { - "illuminate/console": "^9.21|^10.0", - "illuminate/filesystem": "^9.21|^10.0", - "illuminate/support": "^9.21|^10.0", - "illuminate/validation": "^9.21|^10.0", - "php": "^8.0" - }, - "require-dev": { - "orchestra/testbench": "^7.0|^8.0", - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.x-dev" - }, - "laravel": { - "providers": [ - "Laravel\\Ui\\UiServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "Laravel\\Ui\\": "src/", - "Illuminate\\Foundation\\Auth\\": "auth-backend/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "Laravel UI utilities and presets.", - "keywords": [ - "laravel", - "ui" - ], - "support": { - "source": "https://github.com/laravel/ui/tree/v4.2.2" - }, - "time": "2023-05-09T19:47:28+00:00" - }, - { - "name": "openspout/openspout", - "version": "v4.15.0", - "source": { - "type": "git", - "url": "https://github.com/openspout/openspout.git", - "reference": "907a2ff042741b1f25b6e636d18ce9d7fc4c8333" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/openspout/openspout/zipball/907a2ff042741b1f25b6e636d18ce9d7fc4c8333", - "reference": "907a2ff042741b1f25b6e636d18ce9d7fc4c8333", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-fileinfo": "*", - "ext-filter": "*", - "ext-libxml": "*", - "ext-xmlreader": "*", - "ext-zip": "*", - "php": "~8.1.0 || ~8.2.0" - }, - "require-dev": { - "ext-zlib": "*", - "friendsofphp/php-cs-fixer": "^3.18.0", - "infection/infection": "^0.27", - "phpbench/phpbench": "^1.2.10", - "phpstan/phpstan": "^1.10.19", - "phpstan/phpstan-phpunit": "^1.3.13", - "phpstan/phpstan-strict-rules": "^1.5.1", - "phpunit/phpunit": "^10.2.2" - }, - "suggest": { - "ext-iconv": "To handle non UTF-8 CSV files (if \"php-mbstring\" is not already installed or is too limited)", - "ext-mbstring": "To handle non UTF-8 CSV files (if \"iconv\" is not already installed)" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.3.x-dev" - } - }, - "autoload": { - "psr-4": { - "OpenSpout\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Adrien Loison", - "email": "adrien@box.com" - } - ], - "description": "PHP Library to read and write spreadsheet files (CSV, XLSX and ODS), in a fast and scalable way", - "homepage": "https://github.com/openspout/openspout", - "keywords": [ - "OOXML", - "csv", - "excel", - "memory", - "odf", - "ods", - "office", - "open", - "php", - "read", - "scale", - "spreadsheet", - "stream", - "write", - "xlsx" - ], - "support": { - "issues": "https://github.com/openspout/openspout/issues", - "source": "https://github.com/openspout/openspout/tree/v4.15.0" - }, - "funding": [ - { - "url": "https://paypal.me/filippotessarotto", - "type": "custom" - }, - { - "url": "https://github.com/Slamdunk", - "type": "github" - } - ], - "time": "2023-06-19T07:48:22+00:00" - }, { "name": "orchestra/canvas", "version": "v8.11.8", @@ -13804,100 +13109,35 @@ "symfony/var-dumper": "^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4" }, "conflict": { - "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.2" - }, - "suggest": { - "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", - "ext-pdo-sqlite": "The doc command requires SQLite to work.", - "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well." - }, - "bin": [ - "bin/psysh" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "0.12.x-dev" - }, - "bamarni-bin": { - "bin-links": false, - "forward-command": false - } - }, - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "Psy\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Justin Hileman", - "email": "justin@justinhileman.info", - "homepage": "http://justinhileman.com" - } - ], - "description": "An interactive shell for modern PHP.", - "homepage": "http://psysh.org", - "keywords": [ - "REPL", - "console", - "interactive", - "shell" - ], - "support": { - "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.12.2" - }, - "time": "2024-03-17T01:53:00+00:00" - }, - { - "name": "rap2hpoutre/fast-excel", - "version": "v5.2.0", - "source": { - "type": "git", - "url": "https://github.com/rap2hpoutre/fast-excel.git", - "reference": "c6d2b8b707b85f7c43028d3b4cc969388d8b6c17" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/rap2hpoutre/fast-excel/zipball/c6d2b8b707b85f7c43028d3b4cc969388d8b6c17", - "reference": "c6d2b8b707b85f7c43028d3b4cc969388d8b6c17", - "shasum": "" - }, - "require": { - "illuminate/support": "^6.0 || ^7.0 || ^8.0 || ^9.0|^10.0", - "openspout/openspout": "^4.1.1", - "php": "^8.0" + "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" }, "require-dev": { - "illuminate/database": "^6.20.12 || ^7.30.4 || ^8.24.0 || ^9.0|^10.0", - "phpunit/phpunit": "^9.5", - "squizlabs/php_codesniffer": "3.*" + "bamarni/composer-bin-plugin": "^1.2" + }, + "suggest": { + "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", + "ext-pdo-sqlite": "The doc command requires SQLite to work.", + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well." }, + "bin": [ + "bin/psysh" + ], "type": "library", "extra": { - "laravel": { - "providers": [ - "Rap2hpoutre\\FastExcel\\Providers\\FastExcelServiceProvider" - ] + "branch-alias": { + "dev-main": "0.12.x-dev" + }, + "bamarni-bin": { + "bin-links": false, + "forward-command": false } }, "autoload": { "files": [ - "src/functions/fastexcel.php" + "src/functions.php" ], "psr-4": { - "Rap2hpoutre\\FastExcel\\": "src/" + "Psy\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -13906,29 +13146,24 @@ ], "authors": [ { - "name": "rap2h", - "email": "raphaelht@gmail.com" + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" } ], - "description": "Fast Excel import/export for Laravel", + "description": "An interactive shell for modern PHP.", + "homepage": "http://psysh.org", "keywords": [ - "csv", - "excel", - "laravel", - "xls", - "xlsx" + "REPL", + "console", + "interactive", + "shell" ], "support": { - "issues": "https://github.com/rap2hpoutre/fast-excel/issues", - "source": "https://github.com/rap2hpoutre/fast-excel/tree/v5.2.0" + "issues": "https://github.com/bobthecow/psysh/issues", + "source": "https://github.com/bobthecow/psysh/tree/v0.12.2" }, - "funding": [ - { - "url": "https://github.com/rap2hpoutre", - "type": "github" - } - ], - "time": "2023-03-13T14:25:33+00:00" + "time": "2024-03-17T01:53:00+00:00" }, { "name": "spatie/backtrace", @@ -13992,88 +13227,6 @@ ], "time": "2023-06-28T12:59:17+00:00" }, - { - "name": "spatie/laravel-permission", - "version": "5.10.1", - "source": { - "type": "git", - "url": "https://github.com/spatie/laravel-permission.git", - "reference": "d08b3ffc5870cce4a47a39f22174947b33c191ae" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-permission/zipball/d08b3ffc5870cce4a47a39f22174947b33c191ae", - "reference": "d08b3ffc5870cce4a47a39f22174947b33c191ae", - "shasum": "" - }, - "require": { - "illuminate/auth": "^7.0|^8.0|^9.0|^10.0", - "illuminate/container": "^7.0|^8.0|^9.0|^10.0", - "illuminate/contracts": "^7.0|^8.0|^9.0|^10.0", - "illuminate/database": "^7.0|^8.0|^9.0|^10.0", - "php": "^7.3|^8.0" - }, - "require-dev": { - "orchestra/testbench": "^5.0|^6.0|^7.0|^8.0", - "phpunit/phpunit": "^9.4", - "predis/predis": "^1.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.x-dev", - "dev-master": "5.x-dev" - }, - "laravel": { - "providers": [ - "Spatie\\Permission\\PermissionServiceProvider" - ] - } - }, - "autoload": { - "files": [ - "src/helpers.php" - ], - "psr-4": { - "Spatie\\Permission\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "homepage": "https://spatie.be", - "role": "Developer" - } - ], - "description": "Permission handling for Laravel 6.0 and up", - "homepage": "https://github.com/spatie/laravel-permission", - "keywords": [ - "acl", - "laravel", - "permission", - "permissions", - "rbac", - "roles", - "security", - "spatie" - ], - "support": { - "issues": "https://github.com/spatie/laravel-permission/issues", - "source": "https://github.com/spatie/laravel-permission/tree/5.10.1" - }, - "funding": [ - { - "url": "https://github.com/spatie", - "type": "github" - } - ], - "time": "2023-04-12T17:08:32+00:00" - }, { "name": "spatie/laravel-ray", "version": "1.35.1", @@ -14275,68 +13428,6 @@ ], "time": "2024-02-09T09:04:56+00:00" }, - { - "name": "spatie/once", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/spatie/once.git", - "reference": "aab3fc8694e7caec98b2d330c4a8420391c7559d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/once/zipball/aab3fc8694e7caec98b2d330c4a8420391c7559d", - "reference": "aab3fc8694e7caec98b2d330c4a8420391c7559d", - "shasum": "" - }, - "require": { - "php": "^8.0" - }, - "require-dev": { - "pestphp/pest": "^1.21", - "symfony/var-dumper": "^5.1" - }, - "type": "library", - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "Spatie\\Once\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "homepage": "https://spatie.be", - "role": "Developer" - } - ], - "description": "A magic memoization function", - "homepage": "https://github.com/spatie/once", - "keywords": [ - "cache", - "callable", - "memoization", - "once", - "spatie" - ], - "support": { - "source": "https://github.com/spatie/once/tree/3.1.0" - }, - "funding": [ - { - "url": "https://spatie.be/open-source/support-us", - "type": "custom" - } - ], - "time": "2022-04-21T12:23:20+00:00" - }, { "name": "spatie/ray", "version": "1.41.1", @@ -14497,144 +13588,6 @@ ], "time": "2024-01-29T20:11:03+00:00" }, - { - "name": "symfony/polyfill-intl-icu", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-icu.git", - "reference": "a3d9148e2c363588e05abbdd4ee4f971f0a5330c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/a3d9148e2c363588e05abbdd4ee4f971f0a5330c", - "reference": "a3d9148e2c363588e05abbdd4ee4f971f0a5330c", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance and support of other locales than \"en\"" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Icu\\": "" - }, - "classmap": [ - "Resources/stubs" - ], - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's ICU-related data and classes", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "icu", - "intl", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.27.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-11-03T14:55:06+00:00" - }, - { - "name": "vyuldashev/nova-permission", - "version": "v3.2.0", - "source": { - "type": "git", - "url": "https://github.com/vyuldashev/nova-permission.git", - "reference": "2485abfef6d950e8b8b6f0a566da93383e83c6f1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/vyuldashev/nova-permission/zipball/2485abfef6d950e8b8b6f0a566da93383e83c6f1", - "reference": "2485abfef6d950e8b8b6f0a566da93383e83c6f1", - "shasum": "" - }, - "require": { - "laravel/nova": "^4.0", - "php": "^7.4|^8.0", - "spatie/laravel-permission": "^3.0|^4.0|^5.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - }, - "laravel": { - "providers": [ - "Vyuldashev\\NovaPermission\\ToolServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "Vyuldashev\\NovaPermission\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A Laravel Nova tool for Spatie's Permission library.", - "keywords": [ - "laravel", - "nova", - "spatie-permission" - ], - "support": { - "issues": "https://github.com/vyuldashev/nova-permission/issues", - "source": "https://github.com/vyuldashev/nova-permission/tree/v3.2.0" - }, - "time": "2022-08-23T23:14:12+00:00" - }, { "name": "zbateson/mail-mime-parser", "version": "2.4.0", diff --git a/config/fortify.php b/config/fortify.php deleted file mode 100644 index 2303f6270..000000000 --- a/config/fortify.php +++ /dev/null @@ -1,183 +0,0 @@ - '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', - - 'username_alt' => 'username', - - 'email' => 'email', - - /* - |-------------------------------------------------------------------------- - | 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' => config('home'), - - /* - |-------------------------------------------------------------------------- - | Accept invitation route name - |-------------------------------------------------------------------------- - | - | If there is a route for accept an user invitation it should be defined - | here. Note that the route should accept the `$invitation` object - | - */ - 'accept_invitation_route' => 'invitations.accept', - - /* - |-------------------------------------------------------------------------- - | 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', DoNotCacheResponse::class], - - 'middlewares' => [ - 'account_settings' => [ - 'update_profile' => ['web', 'auth'], - 'update_password' => ['web', 'auth'], - ], - ], - - /* - |-------------------------------------------------------------------------- - | 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' => null, - ], - - /* - |-------------------------------------------------------------------------- - | 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([ - 'confirmPassword' => true, - ]), - ], - - /* - |-------------------------------------------------------------------------- - | Models - |-------------------------------------------------------------------------- - | - | Model mapping which allows overriding of models on a per-project basis. - | - */ - - 'models' => [ - 'user' => '', - 'invitation' => '', - ], - - /* - |-------------------------------------------------------------------------- - | Mails - |-------------------------------------------------------------------------- - */ - - 'mail' => [ - 'default' => [ - 'name' => env('MAIL_DEFAULT_NAME', 'ARK Ecosystem'), - 'address' => env('MAIL_DEFAULT_ADDRESS', 'noreply@ark.io'), - ], - - 'feedback' => [ - 'name' => env('MAIL_FEEDBACK_NAME', 'ARK Ecosystem'), - 'address' => env('MAIL_FEEDBACK_ADDRESS', 'feedback@marketsquare.io'), - ], - ], - - /* - |-------------------------------------------------------------------------- - | Routes - |-------------------------------------------------------------------------- - */ - - 'routes' => [ - 'feedback_thank_you' => env('ROUTE_FEEDBACK_THANK_YOU', '/feedback/thank-you'), - 'two_factor_reset_password' => env('ROUTE_TWO_RESET_PASSWORD', '/two-factor/reset-password/{token}'), - 'account_settings_account' => env('ROUTE_ACCOUNT_SETTINGS_ACCOUNT', '/account/settings/account'), - 'account_settings_password' => env('ROUTE_ACCOUNT_SETTINGS_PASSWORD', '/account/settings/password'), - ], - -]; diff --git a/resources/tailwind.config.js b/resources/tailwind.config.js index 345070f12..958bd2d8a 100644 --- a/resources/tailwind.config.js +++ b/resources/tailwind.config.js @@ -227,7 +227,6 @@ module.exports = { content: [ "./resources/views/**/*.blade.php", "./vendor/arkecosystem/foundation/resources/views/**/*.blade.php", - "./vendor/arkecosystem/fortify/resources/views/**/*.blade.php", "./vendor/arkecosystem/hermes/resources/views/**/*.blade.php", "./resources/js/**/*.js", "./resources/js/**/*.vue", diff --git a/resources/views/auth/confirm-password.blade.php b/resources/views/auth/confirm-password.blade.php deleted file mode 100644 index 4c92946ec..000000000 --- a/resources/views/auth/confirm-password.blade.php +++ /dev/null @@ -1 +0,0 @@ -@lang('ui::auth.confirm-password.page_header') diff --git a/resources/views/auth/forgot-password.blade.php b/resources/views/auth/forgot-password.blade.php deleted file mode 100644 index 169ed6711..000000000 --- a/resources/views/auth/forgot-password.blade.php +++ /dev/null @@ -1,41 +0,0 @@ -@extends('layouts.app', ['fullWidth' => true]) - - - -@section('title') - -@endsection - -@section('content') - - -
- - - -
-
- -
-
- -
- - - -
-
-
-@endsection diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php deleted file mode 100644 index b0ee20a56..000000000 --- a/resources/views/auth/login.blade.php +++ /dev/null @@ -1,89 +0,0 @@ -@extends('layouts.app', ['fullWidth' => true]) - - - -@section('title') - -@endsection - -@section('content') - - - -
- @if (session('status')) - - {{ session('status') }} - - @endif - -
- @php - $username = \Laravel\Fortify\Fortify::username(); - $usernameAlt = Config::get('fortify.username_alt'); - $type = 'text'; - - if ($usernameAlt) { - $label = trans('ui::forms.'.$username).' or '.trans('ui::forms.'.$usernameAlt); - } else { - $label = trans('ui::forms.'.$username); - if ($username === 'email') { - $type = 'email'; - } - } - @endphp - - -
- -
- -
- - - @slot('label') - @lang('ui::auth.sign-in.remember_me') - @endslot - - - @php($hasForgotPassword = Route::has('password.request')) - -
-
- @if($hasForgotPassword) - - @endif -
- - -
-
-
- - @if(Route::has('register')) -
- -
- @endif -@endsection diff --git a/resources/views/auth/register-form.blade.php b/resources/views/auth/register-form.blade.php deleted file mode 100644 index aac3df08f..000000000 --- a/resources/views/auth/register-form.blade.php +++ /dev/null @@ -1,108 +0,0 @@ - - @if($invitation) - - - @endif - -
- @if(Config::get('fortify.username_alt')) -
-
- -
-
- @endif - -
-
- -
-
- -
-
- -
-
- - - - - -
-
- -
-
- -
- - @slot('label') - @lang('ui::auth.register-form.conditions', ['termsOfServiceRoute' => route('terms-of-service'), 'privacyPolicyRoute' => route('privacy-policy')]) - @endslot - - - @error('terms') -

{{ $message }}

- @enderror -
- -
- -
-
-
diff --git a/resources/views/auth/register.blade.php b/resources/views/auth/register.blade.php deleted file mode 100644 index e05f12317..000000000 --- a/resources/views/auth/register.blade.php +++ /dev/null @@ -1,19 +0,0 @@ -@extends('layouts.app', ['fullWidth' => true]) - - - -@section('title') - -@endsection - -@section('content') - - - - -
-
- @lang('ui::auth.register-form.already_member', ['route' => route('login')]) -
-
-@endsection diff --git a/resources/views/auth/reset-password-form.blade.php b/resources/views/auth/reset-password-form.blade.php deleted file mode 100644 index 6c55553d8..000000000 --- a/resources/views/auth/reset-password-form.blade.php +++ /dev/null @@ -1,66 +0,0 @@ - - - -
-
-
- -
-
- - - - - -
-
- -
-
- -
- - - -
-
-
diff --git a/resources/views/auth/reset-password.blade.php b/resources/views/auth/reset-password.blade.php deleted file mode 100644 index ad8c7d88f..000000000 --- a/resources/views/auth/reset-password.blade.php +++ /dev/null @@ -1,13 +0,0 @@ -@extends('layouts.app', ['fullWidth' => true]) - - - -@section('title') - -@endsection - -@section('content') - - - -@endsection diff --git a/resources/views/auth/two-factor-challenge.blade.php b/resources/views/auth/two-factor-challenge.blade.php deleted file mode 100644 index a1d9a05b4..000000000 --- a/resources/views/auth/two-factor-challenge.blade.php +++ /dev/null @@ -1,16 +0,0 @@ -@extends('layouts.app', ['fullWidth' => true]) - - - -@section('title') - -@endsection - -@section('content') - - -
- @include('ark-fortify::auth.two-factor.form') - @include('ark-fortify::auth.two-factor.recovery-form') -
-@endsection diff --git a/resources/views/auth/two-factor/form.blade.php b/resources/views/auth/two-factor/form.blade.php deleted file mode 100644 index b04cabce6..000000000 --- a/resources/views/auth/two-factor/form.blade.php +++ /dev/null @@ -1,33 +0,0 @@ - -
- @isset($resetPassword) - - @endisset - -
- -
-
- -
- - - -
-
diff --git a/resources/views/auth/two-factor/recovery-form.blade.php b/resources/views/auth/two-factor/recovery-form.blade.php deleted file mode 100644 index 6e9763845..000000000 --- a/resources/views/auth/two-factor/recovery-form.blade.php +++ /dev/null @@ -1,30 +0,0 @@ - -
- @isset($resetPassword) - - @endisset - -
- -
-
- -
- - - -
-
diff --git a/resources/views/auth/verify-email.blade.php b/resources/views/auth/verify-email.blade.php deleted file mode 100644 index dfbbaf86b..000000000 --- a/resources/views/auth/verify-email.blade.php +++ /dev/null @@ -1,11 +0,0 @@ -@extends('layouts.app') - - - -@section('title') - -@endsection - -@section('content') - -@endsection diff --git a/resources/views/profile/delete-user-form.blade.php b/resources/views/profile/delete-user-form.blade.php deleted file mode 100644 index 2115b80ca..000000000 --- a/resources/views/profile/delete-user-form.blade.php +++ /dev/null @@ -1,95 +0,0 @@ -
-
-

@lang('ui::pages.user-settings.delete_account_title')

- - @lang('ui::pages.user-settings.delete_account_description') - - -
- -
-
- - @if($this->modalShown) - - - @lang('ui::forms.delete-user.title') - - - -
-
- -
- - @if($alert) -
- - {!! $alert !!} - -
- @endif - - @if($showConfirmationMessage) -
- @lang('ui::forms.delete-user.confirmation') -
- @endif -
- - @if($confirmPassword) -
- -
- @elseif($confirmName) -
- @lang ('modals.delete-user.title') -
- -
- -
- @endif - -
- -
-
- - -
- - - -
-
-
- @endif -
diff --git a/resources/views/profile/export-user-data.blade.php b/resources/views/profile/export-user-data.blade.php deleted file mode 100644 index e69def865..000000000 --- a/resources/views/profile/export-user-data.blade.php +++ /dev/null @@ -1,18 +0,0 @@ -
-
- @lang('ui::pages.user-settings.gdpr_title') - @lang('ui::pages.user-settings.gdpr_description') - -
- -
- -
-
rateLimitReached()) data-tippy-content="@lang('ui::messages.export_limit_reached')" @endif > - -
-
-
-
diff --git a/resources/views/profile/feedback-thank-you.blade.php b/resources/views/profile/feedback-thank-you.blade.php deleted file mode 100644 index 94035e449..000000000 --- a/resources/views/profile/feedback-thank-you.blade.php +++ /dev/null @@ -1,20 +0,0 @@ -@extends('layouts.app', ['fullWidth' => true]) - -@section('title') -@lang('ui::metatags.feedback_thank_you') -@endsection - -@section('content') - - -
- - -

@lang('ui::pages.feedback_thank_you.title')

-

@lang('ui::pages.feedback_thank_you.description')

- - @lang('ui::pages.feedback_thank_you.home_page') -
-
- -@endsection diff --git a/resources/views/profile/logout-other-browser-sessions-form.blade.php b/resources/views/profile/logout-other-browser-sessions-form.blade.php deleted file mode 100644 index e9a552d57..000000000 --- a/resources/views/profile/logout-other-browser-sessions-form.blade.php +++ /dev/null @@ -1,185 +0,0 @@ -
-
- @lang('ui::pages.logout-sessions.title') - @lang('ui::pages.logout-sessions.description') - - @lang('ui::pages.logout-sessions.content') - -
- - @if (count($this->sessions) > 0) - - -
- @foreach ($this->sessions as $session) -
- -
-
- @lang('ui::pages.logout-sessions.ip') -
-
-
- {{ $session->ip_address }} -
- @if ($session->agent->isDesktop()) - - @else - - @endif -
-
- -
-
- @lang('ui::pages.logout-sessions.os') -
-
- {{ $session->agent->platform() }} -
-
- -
-
- @lang('ui::pages.logout-sessions.browser') -
-
- {{ $session->agent->browser() }} -
-
- -
-
- @lang('ui::pages.logout-sessions.last_active') -
-
- @if ($session->is_current_device) - @lang('ui::generic.this_device') - @else - @lang('ui::generic.last_active') {{ $session->last_active }} - @endif -
-
- -
- @endforeach -
- @endif -
- -
- - @if($this->modalShown) - - - @lang('ui::forms.confirming-logout.title') - - - -
- -
-
-
- @lang('ui::forms.confirming-logout.content') -
-
-
-
- -
-
-
- - -
- - - -
-
-
- @endif -
diff --git a/resources/views/profile/two-factor-authentication-form.blade.php b/resources/views/profile/two-factor-authentication-form.blade.php deleted file mode 100644 index 5c8a4e0bd..000000000 --- a/resources/views/profile/two-factor-authentication-form.blade.php +++ /dev/null @@ -1,167 +0,0 @@ -@php - use \Illuminate\View\ComponentAttributeBag; - - $twoAuthLink1 = view('ark::external-link', [ - 'attributes' => new ComponentAttributeBag([]), - 'text' => 'Authy', - 'url' => 'https://authy.com', - 'inline' => true, - ])->render(); - - $twoAuthLink2 = view('ark::external-link', [ - 'attributes' => new ComponentAttributeBag([]), - 'text' => 'Google Authenticator', - 'url' => 'https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2', - 'inline' => true, - ])->render(); -@endphp - -
- @if (! $this->enabled) -
-
-
-

- @lang('ui::pages.user-settings.2fa_title') -

- - - @lang('ui::pages.user-settings.2fa_description') - -
- -
-
-
- {!! $this->twoFactorQrCodeSvg !!} -
- -
- - {{ $this->state['two_factor_secret'] }} - -
-
- -
- - @lang('ui::pages.user-settings.2fa_not_enabled_title') - - -
- @lang('ui::pages.user-settings.2fa_summary', [ - 'link1' => $twoAuthLink1, - 'link2' => $twoAuthLink2, - ]) -
- -
- -
-
-
-
- - - -
- -
-
- @else -
-

@lang('ui::pages.user-settings.2fa_title')

- @lang('ui::pages.user-settings.2fa_description') - -
-
- -
- -
- - @lang('ui::pages.user-settings.2fa_enabled_title') - - -
- - @lang('ui::pages.user-settings.2fa_summary', [ - 'link1' => $twoAuthLink1, - 'link2' => $twoAuthLink2, - ]) -
-
-
- -
- - - -
-
- @endif - -
- @if($this->modalShown) - - @endif -
- - @if($this->confirmPasswordShown) - - @endif - - @if($this->disableConfirmPasswordShown) - - @endif -
diff --git a/resources/views/profile/update-password-form.blade.php b/resources/views/profile/update-password-form.blade.php deleted file mode 100644 index 096b7e99c..000000000 --- a/resources/views/profile/update-password-form.blade.php +++ /dev/null @@ -1,72 +0,0 @@ -
-
- @if (flash()->message) -
- -
- @endif - -

- @lang('ui::pages.user-settings.password_information_title') -

- - - @lang('ui::forms.update-password.requirements_notice') - -
- -
-
- - - - - - - - - -
- -
- -
-
-
diff --git a/resources/views/profile/update-profile-information-form.blade.php b/resources/views/profile/update-profile-information-form.blade.php deleted file mode 100644 index d73604f55..000000000 --- a/resources/views/profile/update-profile-information-form.blade.php +++ /dev/null @@ -1,16 +0,0 @@ -
-
- @lang('ui::pages.user-settings.contact_information_title') - @lang('ui::pages.user-settings.contact_information_description') - -
-
- - -
-
- -
-
-
-
diff --git a/resources/views/profile/update-profile-photo-form.blade.php b/resources/views/profile/update-profile-photo-form.blade.php deleted file mode 100644 index f4280019b..000000000 --- a/resources/views/profile/update-profile-photo-form.blade.php +++ /dev/null @@ -1,15 +0,0 @@ -
-
- - -
diff --git a/resources/views/profile/update-timezone-form.blade.php b/resources/views/profile/update-timezone-form.blade.php deleted file mode 100644 index 5214050de..000000000 --- a/resources/views/profile/update-timezone-form.blade.php +++ /dev/null @@ -1,24 +0,0 @@ -
-
- @lang('ui::pages.user-settings.update_timezone_title') - @lang('ui::pages.user-settings.update_timezone_description') -
- -
-
- -
- - @foreach (\ARKEcosystem\Foundation\Support\Timezone::formattedList() as $timezone) - @if ($timezone['timezone'] === $this->user->timezone) - - @else - - @endif - @endforeach - -
-
- -
-
diff --git a/src/Fortify/Components/Concerns/InteractsWithUser.php b/src/Blog/Components/Concerns/InteractsWithUser.php similarity index 82% rename from src/Fortify/Components/Concerns/InteractsWithUser.php rename to src/Blog/Components/Concerns/InteractsWithUser.php index 78d7c48b7..7c89df7de 100644 --- a/src/Fortify/Components/Concerns/InteractsWithUser.php +++ b/src/Blog/Components/Concerns/InteractsWithUser.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace ARKEcosystem\Foundation\Fortify\Components\Concerns; +namespace ARKEcosystem\Foundation\Blog\Components\Concerns; use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Support\Facades\Auth; diff --git a/src/Fortify/Contracts/UserRole.php b/src/Blog/Contracts/UserRole.php similarity index 65% rename from src/Fortify/Contracts/UserRole.php rename to src/Blog/Contracts/UserRole.php index d5977e27d..83aff350a 100644 --- a/src/Fortify/Contracts/UserRole.php +++ b/src/Blog/Contracts/UserRole.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace ARKEcosystem\Foundation\Fortify\Contracts; +namespace ARKEcosystem\Foundation\Blog\Contracts; interface UserRole { diff --git a/src/Fortify/Http/Middleware/EnforceTwoFactorAuthentication.php b/src/Blog/Http/Middleware/EnforceTwoFactorAuthentication.php similarity index 91% rename from src/Fortify/Http/Middleware/EnforceTwoFactorAuthentication.php rename to src/Blog/Http/Middleware/EnforceTwoFactorAuthentication.php index f50013cd7..28b7ced22 100644 --- a/src/Fortify/Http/Middleware/EnforceTwoFactorAuthentication.php +++ b/src/Blog/Http/Middleware/EnforceTwoFactorAuthentication.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace ARKEcosystem\Foundation\Fortify\Http\Middleware; +namespace ARKEcosystem\Foundation\Blog\Http\Middleware; use Closure; use Illuminate\Http\Request; diff --git a/src/Fortify/Models/Concerns/HasLocalizedTimestamps.php b/src/Blog/Models/Concerns/HasLocalizedTimestamps.php similarity index 91% rename from src/Fortify/Models/Concerns/HasLocalizedTimestamps.php rename to src/Blog/Models/Concerns/HasLocalizedTimestamps.php index d0f7a7f4a..966e694a4 100644 --- a/src/Fortify/Models/Concerns/HasLocalizedTimestamps.php +++ b/src/Blog/Models/Concerns/HasLocalizedTimestamps.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace ARKEcosystem\Foundation\Fortify\Models\Concerns; +namespace ARKEcosystem\Foundation\Blog\Models\Concerns; use Carbon\Carbon; use Illuminate\Support\Facades\Auth; diff --git a/src/Blog/Models/User.php b/src/Blog/Models/User.php index 33680e8d0..7ef71735c 100644 --- a/src/Blog/Models/User.php +++ b/src/Blog/Models/User.php @@ -4,24 +4,50 @@ namespace ARKEcosystem\Foundation\Blog\Models; +use ARKEcosystem\Foundation\Blog\Models\Concerns\HasLocalizedTimestamps; use ARKEcosystem\Foundation\Blog\Models\Factories\UserFactory; -use ARKEcosystem\Foundation\Fortify\Models\User as BaseUser; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\SoftDeletes; +use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; +use Illuminate\Support\Str; +use Laravel\Fortify\TwoFactorAuthenticatable; use Spatie\MediaLibrary\HasMedia; use Spatie\MediaLibrary\InteractsWithMedia; +use Spatie\PersonalDataExport\ExportsPersonalData; +use Spatie\PersonalDataExport\PersonalDataSelection; use Spatie\Sluggable\HasSlug; use Spatie\Sluggable\SlugOptions; -class User extends BaseUser implements HasMedia +class User extends Authenticatable implements HasMedia, ExportsPersonalData { use HasSlug; use HasFactory; + use HasLocalizedTimestamps; use Notifiable; use InteractsWithMedia; use SoftDeletes; + use TwoFactorAuthenticatable; + + /** + * The attributes that aren't mass assignable. + * + * @var array|bool + */ + protected $guarded = false; + + /** + * The attributes that should be hidden for arrays. + * + * @var array + */ + protected $hidden = [ + 'password', + 'remember_token', + 'two_factor_recovery_codes', + 'two_factor_secret', + ]; /** * The attributes that should be cast to native types. @@ -60,6 +86,25 @@ public function registerMediaCollections() : void $this->addMediaCollection('photo')->singleFile(); } + /** + * @codeCoverageIgnore + */ + public function selectPersonalData(PersonalDataSelection $personalData): void + { + $personalData->add('user.json', [ + 'name' => $this->name, + 'email' => $this->email, + ]); + } + + /** + * @codeCoverageIgnore + */ + public function personalDataExportName(): string + { + return 'personal-data-'.Str::slug($this->name).'.zip'; + } + /** * Create a new factory instance for the model. * diff --git a/src/Fortify/Actions/AuthenticateUser.php b/src/Fortify/Actions/AuthenticateUser.php deleted file mode 100644 index 9ad688cc3..000000000 --- a/src/Fortify/Actions/AuthenticateUser.php +++ /dev/null @@ -1,66 +0,0 @@ -request = $request; - $this->username = Fortify::username(); - $this->usernameAlt = Config::get('fortify.username_alt'); - } - - public function handle(): ?Authenticatable - { - /** @var \Illuminate\Database\Eloquent\Model */ - $user = $this->fetchUser(); - - if (! $user) { - return null; - } - - if (! Hash::check($this->request->password, $user->password)) { - return null; - } - - $user->update(['last_login_at' => Carbon::now()]); - - return $user; - } - - private function fetchUser(): ?Authenticatable - { - $username = $this->getUsername(); - - $query = Models::user()::query(); - - $query->whereRaw(sprintf('LOWER(%s) = ?', Fortify::username()), [$username]); - - if ($usernameAlt = Config::get('fortify.username_alt')) { - $query->orWhereRaw(sprintf('LOWER(%s) = ?', $usernameAlt), [$username]); - } - - return $query->first(); - } - - private function getUsername(): ?string - { - return strtolower($this->request->get($this->username)); - } -} diff --git a/src/Fortify/Actions/CreateNewUser.php b/src/Fortify/Actions/CreateNewUser.php deleted file mode 100644 index 6bfb91f2f..000000000 --- a/src/Fortify/Actions/CreateNewUser.php +++ /dev/null @@ -1,119 +0,0 @@ -buildValidator($input)->validate(); - $invitation = null; - - if (array_key_exists('invitation', $input)) { - $invitationId = $input['invitation']; - unset($input['invitation']); - $invitation = Models::invitation()::findByUuid($invitationId); - } - - return DB::transaction(function () use ($input, $invitation) { - $user = Models::user()::create($this->getUserData($input)); - - if ($invitation) { - $invitation->update(['user_id' => $user->id]); - } - - return $user; - }); - } - - public static function createValidationRules(): array - { - $rules = [ - 'name' => [ - 'required', - 'max:'.Constants::MAX_DISPLAY_NAME_CHARACTERS, - 'min:'.Constants::MIN_DISPLAY_NAME_CHARACTERS, - new DisplayNameCharacters(), - new OneLetter(), - new StartsWithLetterOrNumber(), - ], - Fortify::username() => static::usernameRules(), - 'password' => static::passwordRules(), - 'password_confirmation' => static::passwordConfirmationRules(), - 'terms' => ['required', 'accepted'], - 'invitation' => ['sometimes', 'required', 'string'], - ]; - - if ($usernameAlt = Config::get('fortify.username_alt')) { - $rules[$usernameAlt] = [ - 'required', 'string', 'unique:users', - ]; - - if ($usernameAlt === 'username') { - $rules[$usernameAlt][] = new Username(); - } elseif ($usernameAlt === 'email') { - $rules[$usernameAlt][] = 'email'; - } - } - - return $rules; - } - - public function getUserData(array $input): array - { - $userData = [ - 'name' => $input['name'], - Fortify::username() => strtolower($input[Fortify::username()]), - 'password' => Hash::make($input['password']), - ]; - - if ($usernameAlt = Config::get('fortify.username_alt')) { - $userData[$usernameAlt] = strtolower($input[$usernameAlt]); - } - - return $userData; - } - - protected static function usernameRules(): array - { - $rules = ['required', 'string', 'max:255', 'unique:users']; - - if (Fortify::username() === 'email') { - $rules[] = 'email'; - } elseif (Fortify::username() === 'username') { - $rules[] = new Username(); - } - - return $rules; - } - - private function buildValidator(array $input): Illuminate - { - return Validator::make($input, static::createValidationRules()); - } -} diff --git a/src/Fortify/Actions/DeleteUser.php b/src/Fortify/Actions/DeleteUser.php deleted file mode 100644 index fdae15116..000000000 --- a/src/Fortify/Actions/DeleteUser.php +++ /dev/null @@ -1,15 +0,0 @@ -delete(); - } -} diff --git a/src/Fortify/Actions/EnableTwoFactorAuthentication.php b/src/Fortify/Actions/EnableTwoFactorAuthentication.php deleted file mode 100644 index 71caf33a5..000000000 --- a/src/Fortify/Actions/EnableTwoFactorAuthentication.php +++ /dev/null @@ -1,49 +0,0 @@ -provider = $provider; - } - - /** - * Enable two factor authentication for the user. - * - * @param mixed $user - * @param string $secretKey - * - * @return void - */ - public function __invoke($user, string $secretKey) - { - $user->forceFill([ - 'two_factor_secret' => encrypt($secretKey), - 'two_factor_recovery_codes' => encrypt(json_encode(Collection::times(8, function () { - return RecoveryCode::generate(); - })->all())), - ])->save(); - } -} diff --git a/src/Fortify/Actions/GenerateTwoFactorAuthenticationSecretKey.php b/src/Fortify/Actions/GenerateTwoFactorAuthenticationSecretKey.php deleted file mode 100644 index af31917dd..000000000 --- a/src/Fortify/Actions/GenerateTwoFactorAuthenticationSecretKey.php +++ /dev/null @@ -1,39 +0,0 @@ -provider = $provider; - } - - /** - * Generate a Two-Factor Authentication Secret Key. - * - * @return string - */ - public function __invoke(): string - { - return $this->provider->generateSecretKey(); - } -} diff --git a/src/Fortify/Actions/PasswordValidationRules.php b/src/Fortify/Actions/PasswordValidationRules.php deleted file mode 100644 index ca99b8125..000000000 --- a/src/Fortify/Actions/PasswordValidationRules.php +++ /dev/null @@ -1,41 +0,0 @@ -letters() - ->mixedCase() - ->numbers() - ->symbols() - ->uncompromised(), - ]; - } - - /** - * Get the validation rules used to validate the confirmed password. - * - * @return array - */ - protected static function passwordConfirmationRules() - { - return [ - 'same:password', - ]; - } -} diff --git a/src/Fortify/Actions/ResetUserPassword.php b/src/Fortify/Actions/ResetUserPassword.php deleted file mode 100644 index a65a06fbe..000000000 --- a/src/Fortify/Actions/ResetUserPassword.php +++ /dev/null @@ -1,38 +0,0 @@ - $this->passwordRules(), - 'password_confirmation' => $this->passwordConfirmationRules(), - ])->after(function ($validator) use ($user, $input) { - if (Hash::check($input['password'], $user->password)) { - $validator->errors()->add('password', trans('ui::validation.password_current')); - } - })->validate(); - - $user->forceFill([ - 'password' => Hash::make($input['password']), - ])->save(); - } -} diff --git a/src/Fortify/Actions/SubscribeToNewsletter.php b/src/Fortify/Actions/SubscribeToNewsletter.php deleted file mode 100644 index 281d1b975..000000000 --- a/src/Fortify/Actions/SubscribeToNewsletter.php +++ /dev/null @@ -1,29 +0,0 @@ - $email, - 'list' => $list, - ], [ - 'email' => ['required', 'email'], - 'list' => ['required', 'string', Rule::in(array_keys(config('newsletter.lists')))], - ])->validate(); - - if (Newsletter::isSubscribed($email, $list)) { - return false; - } - - return Newsletter::subscribePending($email, [], $list) !== false; - } -} diff --git a/src/Fortify/Actions/UpdateUserPassword.php b/src/Fortify/Actions/UpdateUserPassword.php deleted file mode 100644 index 2aff1c25c..000000000 --- a/src/Fortify/Actions/UpdateUserPassword.php +++ /dev/null @@ -1,43 +0,0 @@ - ['required', 'string'], - 'password' => $this->passwordRules(), - 'password_confirmation' => $this->passwordConfirmationRules(), - ])->after(function ($validator) use ($user, $input) { - if (! Hash::check($input['current_password'], $user->password)) { - $validator->errors()->add('current_password', trans('ui::validation.password_doesnt_match')); - } - - if (Hash::check($input['password'], $user->password)) { - $validator->errors()->add('password', trans('ui::validation.password_current')); - } - })->validateWithBag('updatePassword'); - - $user->forceFill([ - 'password' => Hash::make($input['password']), - ])->save(); - } -} diff --git a/src/Fortify/Actions/UpdateUserProfileInformation.php b/src/Fortify/Actions/UpdateUserProfileInformation.php deleted file mode 100644 index 33860b580..000000000 --- a/src/Fortify/Actions/UpdateUserProfileInformation.php +++ /dev/null @@ -1,70 +0,0 @@ - [ - 'required', - 'max:'.Constants::MAX_DISPLAY_NAME_CHARACTERS, - 'min:'.Constants::MIN_DISPLAY_NAME_CHARACTERS, - new DisplayNameCharacters(), - new OneLetter(), - new StartsWithLetterOrNumber(), - ], - 'email' => ['required', 'email', 'max:255', Rule::unique('users')->ignore($user->id)], - ])->validateWithBag('updateProfileInformation'); - - $newEmail = strtolower($input['email']); - $oldEmail = strtolower($user->email); - if ($newEmail !== $oldEmail && $user instanceof MustVerifyEmail) { - $this->updateVerifiedUser($user, $input); - } else { - $user->forceFill([ - 'name' => $input['name'], - 'email' => $newEmail, - ])->save(); - } - } - - /** - * Update the given verified user's profile information. - * - * @param mixed $user - * @param array $input - * - * @return void - */ - protected function updateVerifiedUser($user, array $input) - { - $user->forceFill([ - 'name' => $input['name'], - 'email' => strtolower($input['email']), - 'email_verified_at' => null, - ])->save(); - - $user->sendEmailVerificationNotification(); - } -} diff --git a/src/Fortify/Components/Concerns/ValidatesPassword.php b/src/Fortify/Components/Concerns/ValidatesPassword.php deleted file mode 100644 index 333e5bd05..000000000 --- a/src/Fortify/Components/Concerns/ValidatesPassword.php +++ /dev/null @@ -1,55 +0,0 @@ - false, - 'uppercase' => false, - 'numbers' => false, - 'symbols' => false, - 'min' => false, - 'leak' => false, - ]; - - public function updatedPassword($password) - { - if (is_null($password)) { - return; - } - - $this->passwordRules['lowercase'] = $password && (bool) preg_match('/\p{Ll}/u', $password); - $this->passwordRules['uppercase'] = $password && (bool) preg_match('/\p{Lu}/u', $password); - $this->passwordRules['min'] = $this->passes(Password::min(12), $password); - $this->passwordRules['numbers'] = $this->passes(Password::min(0)->numbers(), $password); - $this->passwordRules['symbols'] = $this->passes(Password::min(0)->symbols(), $password); - $this->passwordRules['leak'] = $this->passes(Password::min(0)->uncompromised(0), $password); - } - - private function passes(Rule $rule, string $password): bool - { - if (! $password) { - return false; - } - - $validator = Validator::make(['password' => $password], [ - 'password' => $rule, - ]); - - return $validator->passes(); - } - - private function resetRules(): void - { - foreach (array_keys($this->passwordRules) as $ruleName) { - $this->passwordRules[$ruleName] = false; - } - } -} diff --git a/src/Fortify/Components/DeleteUserForm.php b/src/Fortify/Components/DeleteUserForm.php deleted file mode 100644 index 60d953128..000000000 --- a/src/Fortify/Components/DeleteUserForm.php +++ /dev/null @@ -1,98 +0,0 @@ -dispatch('confirming-delete-user'); - - $this->openModal(); - } - - public function updated(string $property): void - { - $this->clearValidation($property); - } - - public function deleteUser(DeleteUser $deleter, StatefulGuard $auth) - { - $this->validate(); - - $redirect = $this->sendFeedback(); - - $deleter->delete($this->user->fresh()); - - $auth->logout(); - - $this->redirect($redirect); - } - - public function render() - { - return view('ark-fortify::profile.delete-user-form'); - } - - protected function rules(): array - { - $rules = [ - 'feedback' => 'present|string|min:5|max:500', - ]; - - if ($this->confirmPassword) { - $rules['confirmedPassword'] = ['required', new CurrentPassword($this->user)]; - } - - if ($this->confirmName) { - $rules['confirmedName'] = ['required', new CurrentUserName($this->user)]; - } - - return $rules; - } - - private function sendFeedback(): string - { - if ($this->feedback !== '' && $this->validate()) { - Mail::to(config('fortify.mail.feedback.address'))->send(new SendFeedback($this->feedback)); - - return URL::temporarySignedRoute('profile.feedback.thank-you', now()->addMinutes(15)); - } - - return route('home'); - } -} diff --git a/src/Fortify/Components/ExportUserData.php b/src/Fortify/Components/ExportUserData.php deleted file mode 100644 index 5cdca2e94..000000000 --- a/src/Fortify/Components/ExportUserData.php +++ /dev/null @@ -1,54 +0,0 @@ -rateLimit(1, 15 * 60); - } catch (TooManyRequestsException $exception) { - return; - } - - dispatch(new CreatePersonalDataExportJob($this->user)); - - $this->dispatch('toastMessage', [ - 'message' => trans('ui::pages.user-settings.data_exported'), - 'type' => 'success', - ]); - } - - public function rateLimitReached(): bool - { - return RateLimiter::tooManyAttempts($this->getRateLimitKey('export'), 1); - } - - /** - * Render the component. - * - * @return \Illuminate\View\View - */ - public function render() - { - return view('ark-fortify::profile.export-user-data'); - } -} diff --git a/src/Fortify/Components/FooterEmailSubscriptionForm.php b/src/Fortify/Components/FooterEmailSubscriptionForm.php deleted file mode 100644 index b0e79f837..000000000 --- a/src/Fortify/Components/FooterEmailSubscriptionForm.php +++ /dev/null @@ -1,48 +0,0 @@ -subscribe = false; - $this->status = null; - - $this->subscribed = SubscribeToNewsletter::execute($this->email, config('newsletter.default_list_name')); - - if ($this->subscribed) { - $this->status = trans('ui::messages.subscription.pending'); - } else { - $this->status = trans('ui::messages.subscription.duplicate'); - } - - $this->email = null; - } - - public function updatedEmail(): void - { - $this->validateOnly('email', ['email' => ['required', 'email']]); - } - - /** - * Render the component. - * - * @return \Illuminate\View\View - */ - public function render() - { - return view('ark-fortify::newsletter.footer-subscription-form'); - } -} diff --git a/src/Fortify/Components/LogoutOtherBrowserSessionsForm.php b/src/Fortify/Components/LogoutOtherBrowserSessionsForm.php deleted file mode 100644 index 5ecee88ec..000000000 --- a/src/Fortify/Components/LogoutOtherBrowserSessionsForm.php +++ /dev/null @@ -1,100 +0,0 @@ -password = ''; - - $this->openModal(); - } - - public function updatedPassword() - { - $this->resetErrorBag(); - } - - public function logoutOtherBrowserSessions(StatefulGuard $guard): void - { - $this->resetErrorBag(); - - if (! Hash::check($this->password, Auth::user()->password)) { - throw ValidationException::withMessages([ - 'password' => [trans('ui::validation.password_doesnt_match_records')], - ]); - } - - $guard->logoutOtherDevices($this->password); - - $this->deleteOtherSessionRecords(); - - $this->closeModal(); - - $this->dispatch('loggedOut'); - } - - public function getSessionsProperty(): Collection - { - if (config('session.driver') !== 'database') { - return collect(); - } - - return collect( - DB::table('sessions') - ->where('user_id', Auth::user()->getKey()) - ->orderBy('last_activity', 'desc') - ->take(3)->get() - )->map(function ($session) { - return (object) [ - 'agent' => $this->createAgent($session), - 'ip_address' => $session->ip_address, - 'is_current_device' => $session->id === session()->getId(), - 'last_active' => Carbon::createFromTimestamp($session->last_activity)->diffForHumans(), - ]; - }); - } - - protected function deleteOtherSessionRecords(): void - { - if (config('session.driver') !== 'database') { - return; - } - - DB::connection(config('session.connection'))->table(config('session.table', 'sessions')) - ->where('user_id', Auth::user()->getKey()) - ->where('id', '!=', session()->getId()) - ->delete(); - } - - protected function createAgent(mixed $session): Agent - { - return tap(new Agent(), function ($agent) use ($session) { - $agent->setUserAgent($session->user_agent); - }); - } -} diff --git a/src/Fortify/Components/RegisterForm.php b/src/Fortify/Components/RegisterForm.php deleted file mode 100644 index 0da7adb6e..000000000 --- a/src/Fortify/Components/RegisterForm.php +++ /dev/null @@ -1,127 +0,0 @@ -name = old('name', ''); - $this->email = old('email', ''); - $this->terms = old('terms', false) === true; - - $this->formUrl = request()->fullUrl(); - - $this->invitationId = request()->query('invitation'); - - if ($this->invitationId !== null) { - $this->email = $this->findInvitation()?->email ?? ''; - } - } - - /** - * Render the component. - * - * @return \Illuminate\View\View - */ - public function render() - { - return view('ark-fortify::auth.register-form', [ - 'invitation' => $this->invitationId ? $this->findInvitation() : null, - ]); - } - - public function canSubmit(): bool - { - foreach ($this->requiredProperties as $property) { - if (! $this->$property) { - return false; - } - } - - return $this->getErrorBag()->count() === 0; - } - - public function updated(string $propertyName, mixed $value): void - { - if ($propertyName === 'email') { - $value = strtolower($value); - - // Prevent email address updates if user wants to sign up via invitation... - if ($this->invitationId) { - $this->email = $this->findInvitation()?->email ?? ''; - } - } - - $values = [$propertyName => $value]; - $rules = [$propertyName => $this->rules()[$propertyName]]; - - if ($propertyName === 'password') { - $values['password_confirmation'] = $this->password_confirmation; - $rules['password_confirmation'] = $this->rules()['password_confirmation']; - - $this->resetErrorBag([$propertyName, 'password_confirmation']); - } elseif ($propertyName === 'password_confirmation') { - $values['password'] = $this->password; - } - - $validator = Validator::make($values, $rules); - - if ($validator->fails()) { - $this->setErrorBag( - $validator->getMessageBag()->merge($this->getErrorBag()) - ); - - return; - } - - $this->resetErrorBag($propertyName); - } - - protected function rules(): array - { - return collect(resolve(CreatesNewUsers::class)::createValidationRules()) - ->filter(fn ($value, $key) => property_exists($this, $key)) - ->toArray(); - } - - private function findInvitation() : ?Model - { - return Models::invitation()::findByUuid($this->invitationId); - } -} diff --git a/src/Fortify/Components/ResetPasswordForm.php b/src/Fortify/Components/ResetPasswordForm.php deleted file mode 100644 index b6965f21d..000000000 --- a/src/Fortify/Components/ResetPasswordForm.php +++ /dev/null @@ -1,47 +0,0 @@ -token = $token; - - if ($email !== null) { - $this->email = $email; - - $user = Models::user()::where('email', $email)->firstOrFail(); - - $this->twoFactorSecret = $user->two_factor_secret; - } - } - - /** - * Render the component. - * - * @return \Illuminate\View\View - */ - public function render() - { - return view('ark-fortify::auth.reset-password-form'); - } -} diff --git a/src/Fortify/Components/TwoFactorAuthenticationForm.php b/src/Fortify/Components/TwoFactorAuthenticationForm.php deleted file mode 100644 index 3cf386e83..000000000 --- a/src/Fortify/Components/TwoFactorAuthenticationForm.php +++ /dev/null @@ -1,192 +0,0 @@ - 'Please provide an OTP', - 'state.otp.digits' => 'One Time Password must be :digits digits.', - ]; - - public function mount(): void - { - if (! $this->enabled) { - $this->generateSecretKey(); - } - } - - public function render(): View - { - return view('ark-fortify::profile.two-factor-authentication-form'); - } - - public function updatedStateOtp(): void - { - $this->resetValidation(); - } - - public function enableTwoFactorAuthentication(): void - { - $this->validate([ - 'state.otp' => ['required', 'digits:6', new OneTimePassword($this->state['two_factor_secret'])], - ]); - - app(EnableTwoFactorAuthentication::class)(Auth::user(), $this->state['two_factor_secret']); - - $this->showingQrCode = true; - $this->state['otp'] = null; - $this->showRecoveryCodes(); - - // Not used on this component internally but useful to send a message - // to other components that the user enabled 2FA. - $this->dispatch('twoFactorAuthenticationEnabled'); - } - - public function showRecoveryCodes(): void - { - $this->openModal(); - } - - public function regenerateRecoveryCodes(): void - { - app(GenerateNewRecoveryCodes::class)(Auth::user()); - - $this->showRecoveryCodes(); - } - - public function disableTwoFactorAuthentication(): void - { - $this->validate(); - - app(DisableTwoFactorAuthentication::class)(Auth::user()); - - $this->generateSecretKey(); - $this->closeDisableConfirmPassword(); - - $this->dispatch('toastMessage', [ - 'message' => trans('ui::messages.2fa_disabled'), - 'type' => 'success', - ]); - - // Not used on this component internally but useful to send a message - // to other components that the user disabled 2FA. - $this->dispatch('twoFactorAuthenticationDisabled'); - } - - public function getEnabledProperty(): bool - { - return ! empty($this->user->two_factor_secret); - } - - public function getTwoFactorQrCodeSvgProperty(): string - { - $svg = (new Writer( - new ImageRenderer( - new RendererStyle(170, 0, null, null, Fill::uniformColor(new Rgb(255, 255, 255), new Rgb(45, 55, 72))), - new SvgImageBackEnd() - ) - ))->writeString($this->twoFactorQrCodeUrl); - - return trim(substr($svg, strpos($svg, "\n") + 1)); - } - - public function getTwoFactorQrCodeUrlProperty(): string - { - return app(TwoFactorAuthenticationProvider::class)->qrCodeUrl( - config('app.name'), - (string) data_get($this->user, config('fortify.username'), 'email'), - $this->state['two_factor_secret'] - ); - } - - public function hideRecoveryCodes(): void - { - $this->closeModal(); - } - - public function showConfirmPassword(): void - { - $this->resetValidation(); - $this->confirmPasswordShown = true; - $this->confirmedPassword = ''; - } - - public function closeConfirmPassword(): void - { - $this->confirmPasswordShown = false; - $this->confirmedPassword = ''; - - $this->modalClosed(); - } - - public function showDisableConfirmPassword(): void - { - $this->resetValidation(); - $this->disableConfirmPasswordShown = true; - $this->confirmedPassword = ''; - } - - public function closeDisableConfirmPassword(): void - { - $this->disableConfirmPasswordShown = false; - $this->confirmedPassword = ''; - - $this->modalClosed(); - } - - public function showRecoveryCodesAfterPasswordConfirmation(): void - { - $this->validate(); - - $this->closeConfirmPassword(); - - $this->showRecoveryCodes(); - } - - protected function rules() - { - return [ - 'confirmedPassword' => ['required', new CurrentPassword(Auth::user())], - ]; - } - - private function generateSecretKey(): void - { - $this->state['two_factor_secret'] = app(GenerateTwoFactorAuthenticationSecretKey::class)(); - } -} diff --git a/src/Fortify/Components/UpdatePasswordForm.php b/src/Fortify/Components/UpdatePasswordForm.php deleted file mode 100644 index 701c59fa4..000000000 --- a/src/Fortify/Components/UpdatePasswordForm.php +++ /dev/null @@ -1,70 +0,0 @@ - 'passwordUpdated']; - - /** - * Update the user's password. - * - * @param \Laravel\Fortify\Contracts\UpdatesUserPasswords $updater - * - * @return void - */ - public function updatePassword(UpdatesUserPasswords $updater) - { - $this->resetErrorBag(); - - $updater->update(Auth::user(), [ - 'current_password' => $this->currentPassword, - 'password' => $this->password, - 'password_confirmation' => $this->password_confirmation, - ]); - - $this->currentPassword = ''; - $this->password = ''; - $this->password_confirmation = ''; - - $this->dispatch('updated-password'); - $this->resetRules(); - - $this->dispatch('toastMessage', [ - 'message' => trans('ui::pages.user-settings.password_updated'), - 'type' => 'success', - ]); - } - - public function updated(string $property): void - { - $this->clearValidation($property); - } - - /** - * Render the component. - * - * @return \Illuminate\View\View - */ - public function render() - { - return view('ark-fortify::profile.update-password-form'); - } -} diff --git a/src/Fortify/Components/UpdateProfileInformationForm.php b/src/Fortify/Components/UpdateProfileInformationForm.php deleted file mode 100644 index 7936dbbac..000000000 --- a/src/Fortify/Components/UpdateProfileInformationForm.php +++ /dev/null @@ -1,67 +0,0 @@ -state = Auth::user()->withoutRelations()->toArray(); - } - - /** - * Update the user's profile information. - * - * @param \Laravel\Fortify\Contracts\UpdatesUserProfileInformation $updater - * - * @return void - */ - public function updateProfileInformation(UpdatesUserProfileInformation $updater) - { - $this->resetErrorBag(); - - $updater->update(Auth::user(), $this->state); - - $this->dispatch('saved'); - - $this->dispatch('refresh-navigation-dropdown'); - - $this->dispatch('toastMessage', [ - 'message' => trans('ui::pages.user-settings.profile_updated'), - 'type' => 'success', - ]); - } - - /** - * Render the component. - * - * @return \Illuminate\View\View - */ - public function render() - { - return view('ark-fortify::profile.update-profile-information-form'); - } -} diff --git a/src/Fortify/Components/UpdateProfilePhotoForm.php b/src/Fortify/Components/UpdateProfilePhotoForm.php deleted file mode 100644 index fd6f0d9b8..000000000 --- a/src/Fortify/Components/UpdateProfilePhotoForm.php +++ /dev/null @@ -1,70 +0,0 @@ -dimensions = $dimensions; - $this->alignment = $alignment; - $this->formClass = $formClass; - $this->withCrop = $withCrop; - $this->cropOptions = $cropOptions; - } - - public function render(): View - { - return view('ark-fortify::profile.update-profile-photo-form'); - } - - public function updatedImageSingle(): void - { - if (! is_a($this->imageSingle, TemporaryUploadedFile::class)) { - $this->imageSingle = TemporaryUploadedFile::createFromLivewire($this->imageSingle); - } - - $this->validateImageSingle(); - - $this->user - ->addMedia($this->imageSingle->getRealPath()) - ->withResponsiveImages() - ->usingName($this->imageSingle->hashName()) - ->toMediaCollection('photo'); - - $this->user->refresh(); - } - - public function deleteImageSingle(): void - { - $this->user->getFirstMedia('photo')->delete(); - $this->user->refresh(); - - if (is_a($this->imageSingle, TemporaryUploadedFile::class)) { - $this->imageSingle->delete(); - } - - $this->imageSingle = null; - } -} diff --git a/src/Fortify/Components/UpdateTimezoneForm.php b/src/Fortify/Components/UpdateTimezoneForm.php deleted file mode 100644 index cfb962db3..000000000 --- a/src/Fortify/Components/UpdateTimezoneForm.php +++ /dev/null @@ -1,54 +0,0 @@ -timezone = $this->user->timezone; - } - - /** - * Render the component. - * - * @return \Illuminate\View\View - */ - public function render() - { - return view('ark-fortify::profile.update-timezone-form'); - } - - public function updateTimezone(): void - { - $data = $this->validate([ - 'timezone' => [ - 'required', - Rule::in(Timezone::list()), - ], - ]); - - $this->user->timezone = $data['timezone']; - - $this->user->save(); - - $this->dispatch('toastMessage', [ - 'message' => trans('ui::pages.user-settings.timezone_updated'), - 'type' => 'success', - ]); - } -} diff --git a/src/Fortify/Components/VerifyEmail.php b/src/Fortify/Components/VerifyEmail.php deleted file mode 100644 index 5ccf613c7..000000000 --- a/src/Fortify/Components/VerifyEmail.php +++ /dev/null @@ -1,42 +0,0 @@ -rateLimit(self::MAX_ATTEMPTS, self::DECAY_SECONDS); - } catch (TooManyRequestsException $e) { - return; - } - - (new EmailVerificationNotificationController())->store(request()); - } - - public function rateLimitReached(): bool - { - return RateLimiter::tooManyAttempts($this->getRateLimitKey('resend'), self::MAX_ATTEMPTS); - } -} diff --git a/src/Fortify/Console/Commands/CreateUserCommand.php b/src/Fortify/Console/Commands/CreateUserCommand.php deleted file mode 100644 index 9cc4ecc35..000000000 --- a/src/Fortify/Console/Commands/CreateUserCommand.php +++ /dev/null @@ -1,90 +0,0 @@ -option('domain')))); - $name = strtolower(Arr::first(Arr::wrap($this->argument('name')))); - $email = $name.'@'.$domain; - $roles = (array) $this->option('role'); - - $isProduction = app()->environment() === 'production'; - - if ($this->option('silent') === true || $this->confirm("Do you want to create an account as {$email}?")) { - $data = $this->getUserData($name, $domain); - - $password = null; - if ($isProduction) { - $data['password'] = Hash::make($password = Str::random(32)); - } else { - $data['password'] = Hash::make('password'); - } - - $user = Models::user()::create($data); - - if (count($roles) > 0) { - foreach ($roles as $role) { - $user->assignRole($role); - } - } - - $this->info('The account has been created.'); - if ($isProduction) { - $this->info('An E-Mail with further instructions has been sent.'); - - $user->notify(new AccountCreated($password)); - } - } - } - - protected function getUserData(string $name, string $domain): array - { - $data = [ - 'username' => $name, - 'email' => $name.'@'.$domain, - 'email_verified_at' => Carbon::now(), - ]; - - if (Schema::hasColumn('users', 'name')) { - $data['name'] = ucwords($name); - } - - return $data; - } -} diff --git a/src/Fortify/Console/Commands/RunPlaybookCommand.php b/src/Fortify/Console/Commands/RunPlaybookCommand.php deleted file mode 100644 index d8d905d58..000000000 --- a/src/Fortify/Console/Commands/RunPlaybookCommand.php +++ /dev/null @@ -1,147 +0,0 @@ -environment() !== 'local') { - $this->error('This command can only be run in the local environment!'); - } - - $playbookName = $this->argument('playbook'); - - if ($playbookName === null) { - $availablePlaybooks = $this->getAvailablePlaybooks(); - - $this->comment('Choose a playbook: '.PHP_EOL); - - foreach ($availablePlaybooks as $availablePlaybook) { - $this->comment("- {$availablePlaybook}"); - } - - $this->comment(''); - - $playbookName = $this->askPlaybookName($availablePlaybooks); - } - - $playbookDefinition = $this->resolvePlaybookDefinition($playbookName); - - $this->migrate(); - - $this->runPlaybook($playbookDefinition); - } - - private function migrate(): void - { - $this->info('Clearing the database'); - - $this->call('migrate:fresh', ['--force']); - } - - private function runPlaybook(PlaybookDefinition $definition): void - { - foreach ($definition->playbook->before() as $before) { - $this->runPlaybook( - $this->resolvePlaybookDefinition($before) - ); - } - - for ($i = 1; $i <= $definition->times; $i++) { - if ($definition->once && $this->definitionHasRun($definition)) { - break; - } - - $this->infoRunning($definition->playbook, $i); - - $definition->playbook->run($this->input, $this->output); - - $definition->playbook->hasRun(); - - $this->ranDefinitions[$definition->id] = ($this->ranDefinitions[$definition->id] ?? 0) + 1; - } - - foreach ($definition->playbook->after() as $after) { - $this->runPlaybook( - $this->resolvePlaybookDefinition($after) - ); - } - } - - private function askPlaybookName(array $availablePlaybooks): string - { - $helper = $this->getHelper('question'); - - $question = new Question(''); - - $question->setAutocompleterValues($availablePlaybooks); - - $playbookName = (string) $helper->ask($this->input, $this->output, $question); - - if ($playbookName === '') { - $this->error('Please choose a playbook'); - - return $this->askPlaybookName($availablePlaybooks); - } - - return $playbookName; - } - - private function getAvailablePlaybooks(): array - { - /** - * @var array - */ - $files = scandir(__DIR__.'/../Playbooks'); - - unset($files[0], $files[1]); - - return array_map(fn (string $file) => str_replace('.php', '', $file), $files); - } - - private function resolvePlaybookDefinition(mixed $class): PlaybookDefinition - { - if ($class instanceof PlaybookDefinition) { - return $class; - } - - if ($class instanceof Playbook) { - return new PlaybookDefinition($class::class); - } - - $className = $class; - - if (! Str::startsWith($class, ['\\App\\Console\\Playbooks', 'App\\Console\\Playbooks'])) { - $className = "\\App\\Console\\Playbooks\\{$class}"; - } - - return new PlaybookDefinition($className); - } - - private function infoRunning(Playbook $playbook, int $i): void - { - $playbookName = $playbook::class; - - $this->info("Running playbook `{$playbookName}` (#{$i})"); - } - - private function definitionHasRun(PlaybookDefinition $definition): bool - { - return array_key_exists($definition->id, $this->ranDefinitions); - } -} diff --git a/src/Fortify/Console/Playbooks/AccessControlPlaybook.php b/src/Fortify/Console/Playbooks/AccessControlPlaybook.php deleted file mode 100644 index fa57936fa..000000000 --- a/src/Fortify/Console/Playbooks/AccessControlPlaybook.php +++ /dev/null @@ -1,53 +0,0 @@ -forgetCachedPermissions(); - - foreach (app(UserRole::class)::toArray() as $role) { - Role::firstOrCreate(['name' => $role]); - } - - $guardName = Guard::getDefaultName(Permission::class); - $permissions = collect(); - foreach ($this->actions as $action) { - foreach ($resources as $resource) { - $permissions->add([ - 'name' => "{$action} {$resource}", - 'guard_name' => $guardName, - ]); - } - } - - Permission::upsert($permissions->toArray(), ['id']); - - PermissionMapping::mapToRoles(); - } -} diff --git a/src/Fortify/Console/Playbooks/DemoPlaybook.php b/src/Fortify/Console/Playbooks/DemoPlaybook.php deleted file mode 100644 index 9845d707c..000000000 --- a/src/Fortify/Console/Playbooks/DemoPlaybook.php +++ /dev/null @@ -1,24 +0,0 @@ -writeln('[Playbook] Demo - success'); - } -} diff --git a/src/Fortify/Console/Playbooks/ManagementUserPlaybook.php b/src/Fortify/Console/Playbooks/ManagementUserPlaybook.php deleted file mode 100644 index 56a4d3190..000000000 --- a/src/Fortify/Console/Playbooks/ManagementUserPlaybook.php +++ /dev/null @@ -1,32 +0,0 @@ - $user) { - foreach ($user as $name => $roles) { - $rolesSignature = collect($roles) - ->map(fn ($role) => '--role='.$role) - ->join(' '); - - Artisan::call(sprintf( - 'user:create %s %s --silent --domain=%s', - $name, - $rolesSignature, - $domain - )); - } - } - } -} diff --git a/src/Fortify/Console/Playbooks/Playbook.php b/src/Fortify/Console/Playbooks/Playbook.php deleted file mode 100644 index 2e140b916..000000000 --- a/src/Fortify/Console/Playbooks/Playbook.php +++ /dev/null @@ -1,45 +0,0 @@ -playbook = app($className); - $this->id = $this->playbook::class; - } - - public static function times(string $className, int $times): self - { - $definition = new static($className); - - $definition->times = $times; - - return $definition; - } - - public static function once(string $className): self - { - $definition = new static($className); - - $definition->once = true; - - return $definition; - } -} diff --git a/src/Fortify/Contracts/DeleteUser.php b/src/Fortify/Contracts/DeleteUser.php deleted file mode 100644 index 746f0be3e..000000000 --- a/src/Fortify/Contracts/DeleteUser.php +++ /dev/null @@ -1,17 +0,0 @@ -hasChallengedUser()) { - throw new HttpResponseException(redirect()->route('login')); - } - - if (! $request->hasValidToken()) { - throw new HttpResponseException(redirect()->route('login')->withErrors(['email' => trans('ui::validation.password_reset_link_invalid')])); - } - - return view('ark-fortify::auth.two-factor-challenge', [ - 'token' => $token, - 'resetPassword' => true, - 'email' => $request->challengedUser()->email, - ]); - } - - /** - * Validates the 2fa code and shows the reset password form. - * - * @param TwoFactorResetPasswordRequest $request - * - * @return mixed - */ - public function store(TwoFactorResetPasswordRequest $request) - { - $user = $request->challengedUser(); - - if (! $request->hasValidToken()) { - throw new HttpResponseException(redirect()->route('login')->withErrors(['email' => trans('ui::validation.password_reset_link_invalid')])); - } - - if ($code = $request->validRecoveryCode()) { - $user->replaceRecoveryCode($code); - } elseif (! $request->hasValidCode()) { - return app(FailedTwoFactorLoginResponse::class); - } - - return view('ark-fortify::auth.reset-password'); - } -} diff --git a/src/Fortify/Http/Requests/TwoFactorResetPasswordRequest.php b/src/Fortify/Http/Requests/TwoFactorResetPasswordRequest.php deleted file mode 100644 index 4f00c180c..000000000 --- a/src/Fortify/Http/Requests/TwoFactorResetPasswordRequest.php +++ /dev/null @@ -1,62 +0,0 @@ -challengedUser(); - - return $user && app(PasswordBroker::class)->tokenExists($user, $this->route('token')); - } - - /** - * Determine if there is a challenged user in the current session. - * - * @return bool - */ - public function hasChallengedUser() - { - $model = app(StatefulGuard::class)->getProvider()->getModel(); - - return $this->has('email') && - $model::whereEmail($this->get('email'))->exists(); - } - - /** - * 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->has('email') || - ! $user = $model::whereEmail($this->get('email'))->first()) { - throw new HttpResponseException( - app(FailedTwoFactorLoginResponse::class)->toResponse($this) - ); - } - - return $this->challengedUser = $user; - } -} diff --git a/src/Fortify/Http/Responses/FailedPasswordResetLinkRequestResponse.php b/src/Fortify/Http/Responses/FailedPasswordResetLinkRequestResponse.php deleted file mode 100644 index c51acb1aa..000000000 --- a/src/Fortify/Http/Responses/FailedPasswordResetLinkRequestResponse.php +++ /dev/null @@ -1,31 +0,0 @@ -status, [Password::RESET_LINK_SENT, Password::INVALID_USER], true)) { - return app(SuccessfulPasswordResetLinkRequestResponse::class, ['status' => $this->status])->toResponse($request); - } - - return parent::toResponse($request); - } -} diff --git a/src/Fortify/Http/Responses/SuccessfulPasswordResetLinkRequestResponse.php b/src/Fortify/Http/Responses/SuccessfulPasswordResetLinkRequestResponse.php deleted file mode 100644 index cc42039e2..000000000 --- a/src/Fortify/Http/Responses/SuccessfulPasswordResetLinkRequestResponse.php +++ /dev/null @@ -1,27 +0,0 @@ -success(__('pages.user-settings.reset_link_email')); - - return $request->wantsJson() - ? new JsonResponse(['message' => trans($this->status)], 200) - : back()->with('status', trans($this->status)); - } -} diff --git a/src/Fortify/Mail/SendFeedback.php b/src/Fortify/Mail/SendFeedback.php deleted file mode 100644 index faeb2d4de..000000000 --- a/src/Fortify/Mail/SendFeedback.php +++ /dev/null @@ -1,29 +0,0 @@ -message = $message; - } - - public function build(): self - { - return $this - ->from(config('fortify.mail.default.address'), config('fortify.mail.default.name')) - ->subject(trans('ui::mails.feedback_subject')) - ->markdown('ark-fortify::mails.profile.feedback'); - } -} diff --git a/src/Fortify/Models.php b/src/Fortify/Models.php deleted file mode 100644 index 7aa670c84..000000000 --- a/src/Fortify/Models.php +++ /dev/null @@ -1,28 +0,0 @@ -getFirstMedia('photo'); - } - - public function getPhotoAttribute(): string - { - return $this->getFirstMediaUrl('photo'); - } - - public function registerMediaCollections(): void - { - $this->addMediaCollection('photo')->singleFile(); - } -} diff --git a/src/Fortify/Models/Permission.php b/src/Fortify/Models/Permission.php deleted file mode 100644 index 7329e1328..000000000 --- a/src/Fortify/Models/Permission.php +++ /dev/null @@ -1,60 +0,0 @@ -filter(fn (string $resource) => str_starts_with($resource, 'App\\Nova\\')) - ->map(fn ($resource) => Str::of($resource)->after('App\\Nova\\')->lower()->plural()) - ->sort() - ->values(); - - $order = $resources - ->map(fn ($resource, $index) => "WHEN name like '% $resource' THEN $index") - ->join(' '); - - return $query - ->where(fn ($query) => $resources->each(fn ($resource) => $query->orWhere('name', 'like', '% '.$resource))) - ->orderByRaw("CASE $order END ASC") - ->orderBy('name'); - } - - /** - * The "booted" method of the model. - * - * @return void - */ - protected static function booted() - { - static::updating(function ($permission) : void { - $cachekey = static::getCacheKey($permission->getOriginal('name'), $permission->getOriginal('guard_name')); - Cache::forget($cachekey); - }); - - static::deleted(function ($permission) : void { - $cachekey = static::getCacheKey($permission->name, $permission->guard_name); - Cache::forget($cachekey); - }); - - static::created(function ($permission) : void { - $cachekey = static::getCacheKey($permission->name, $permission->guard_name); - Cache::forget($cachekey); - }); - } -} diff --git a/src/Fortify/Models/User.php b/src/Fortify/Models/User.php deleted file mode 100644 index d438917be..000000000 --- a/src/Fortify/Models/User.php +++ /dev/null @@ -1,19 +0,0 @@ -hasRole([ - app(UserRole::class)::SUPER_ADMIN, - app(UserRole::class)::ADMIN, - ]); - } -} diff --git a/src/Fortify/Models/UserWithoutVerification.php b/src/Fortify/Models/UserWithoutVerification.php deleted file mode 100644 index ce975ccc3..000000000 --- a/src/Fortify/Models/UserWithoutVerification.php +++ /dev/null @@ -1,78 +0,0 @@ - 'datetime', - ]; - - /** - * @codeCoverageIgnore - */ - public function selectPersonalData(PersonalDataSelection $personalData): void - { - $personalData->add('user.json', [ - 'name' => $this->name, - 'email' => $this->email, - ]); - } - - /** - * @codeCoverageIgnore - */ - public function personalDataExportName(): string - { - return 'personal-data-'.Str::slug($this->name).'.zip'; - } - - /** - * Create a new factory instance for the model. - * - * @return \Illuminate\Database\Eloquent\Factories\Factory - */ - protected static function newFactory() - { - return new UserFactory(); - } -} diff --git a/src/Fortify/Notifications/AccountCreated.php b/src/Fortify/Notifications/AccountCreated.php deleted file mode 100644 index f122e0bd8..000000000 --- a/src/Fortify/Notifications/AccountCreated.php +++ /dev/null @@ -1,48 +0,0 @@ -line("The password for your account is **{$this->password}**.") - ->action('Login', route('login')) - ->line('Please delete this e-mail after logging in and storing the password.'); - } -} diff --git a/src/Fortify/Nova/Fields/PermissionBooleanGroup.php b/src/Fortify/Nova/Fields/PermissionBooleanGroup.php deleted file mode 100644 index 0bbcce993..000000000 --- a/src/Fortify/Nova/Fields/PermissionBooleanGroup.php +++ /dev/null @@ -1,51 +0,0 @@ -pluck($labelAttribute ?? 'name', 'name')->toArray(); - - $this->options($options); - } - - /** - * @param NovaRequest $request - * @param string $requestAttribute - * @param HasPermissions $model - * @param string $attribute - */ - protected function fillAttributeFromRequest(NovaRequest $request, $requestAttribute, $model, $attribute) - { - $currentPermissions = $model->permissions; - - parent::fillAttributeFromRequest($request, $requestAttribute, $model, $attribute); - - $model->permissions->each(function ($permission) { - $cachekey = Permission::getCacheKey($permission->name, $permission->guard_name); - Cache::forget($cachekey); - }); - - $currentPermissions->each(function ($permission) { - $cachekey = Permission::getCacheKey($permission->name, $permission->guard_name); - Cache::forget($cachekey); - }); - } -} diff --git a/src/Fortify/Nova/Fields/RoleBooleanGroup.php b/src/Fortify/Nova/Fields/RoleBooleanGroup.php deleted file mode 100644 index 32a0c3bf2..000000000 --- a/src/Fortify/Nova/Fields/RoleBooleanGroup.php +++ /dev/null @@ -1,28 +0,0 @@ -name, $model->guard_name); - Cache::forget($cachekey); - } -} diff --git a/src/Fortify/Nova/Permission.php b/src/Fortify/Nova/Permission.php deleted file mode 100644 index 021f7a2c6..000000000 --- a/src/Fortify/Nova/Permission.php +++ /dev/null @@ -1,49 +0,0 @@ -novaResources(); - } - - /** - * Get the fields displayed by the resource. - * - * @param Request $request - * - * @return array - */ - public function fields(Request $request): array - { - $fields = parent::fields($request); - - $fieldIndex = collect($fields) - ->filter(fn ($field) => get_class($field) === VyuldashevRoleBooleanGroup::class) - ->keys() - ->first(); - - $fields[$fieldIndex] = RoleBooleanGroup::make(__('nova-permission-tool::permissions.roles'), 'roles'); - - return $fields; - } -} diff --git a/src/Fortify/Nova/Role.php b/src/Fortify/Nova/Role.php deleted file mode 100644 index 9e2db2e30..000000000 --- a/src/Fortify/Nova/Role.php +++ /dev/null @@ -1,34 +0,0 @@ -filter(fn ($field) => get_class($field) === VyuldashevPermissionBooleanGroup::class) - ->keys() - ->first(); - - $fields[$fieldIndex] = PermissionBooleanGroup::make(__('nova-permission-tool::roles.permissions'), 'permissions'); - - return $fields; - } -} diff --git a/src/Fortify/Policies/Concerns/HasDefaultPolicyRules.php b/src/Fortify/Policies/Concerns/HasDefaultPolicyRules.php deleted file mode 100644 index 2c18291fc..000000000 --- a/src/Fortify/Policies/Concerns/HasDefaultPolicyRules.php +++ /dev/null @@ -1,48 +0,0 @@ -hasPermissionTo($user, 'viewAny'); - } - - public function view(mixed $user): bool - { - return $this->hasPermissionTo($user, 'view'); - } - - public function create(mixed $user): bool - { - return $this->hasPermissionTo($user, 'create'); - } - - public function update(mixed $user): bool - { - return $this->hasPermissionTo($user, 'update'); - } - - public function delete(mixed $user): bool - { - return $this->hasPermissionTo($user, 'delete'); - } - - public function restore(mixed $user): bool - { - return $this->hasPermissionTo($user, 'restore'); - } - - public function forceDelete(mixed $user): bool - { - return $this->hasPermissionTo($user, 'forceDelete'); - } - - private function hasPermissionTo($user, string $action): bool - { - return $user->hasPermissionTo("{$action} {$this->resourceName}"); - } -} diff --git a/src/Fortify/Policies/PermissionPolicy.php b/src/Fortify/Policies/PermissionPolicy.php deleted file mode 100644 index 0d5d0b29f..000000000 --- a/src/Fortify/Policies/PermissionPolicy.php +++ /dev/null @@ -1,53 +0,0 @@ -isSuperAdmin($user); - } - - public function view($user, Permission $permission) - { - return $this->isSuperAdmin($user); - } - - public function create($user) - { - return $this->isSuperAdmin($user); - } - - public function update($user, Permission $permission) - { - return $this->isSuperAdmin($user); - } - - public function delete($user, Permission $permission) - { - return $this->isSuperAdmin($user); - } - - public function restore($user, Permission $permission) - { - return $this->isSuperAdmin($user); - } - - public function forceDelete($user, Permission $permission) - { - return $this->isSuperAdmin($user); - } - - private function isSuperAdmin($user): bool - { - return $user->hasRole([ - app(UserRole::class)::SUPER_ADMIN, - ]); - } -} diff --git a/src/Fortify/Policies/Policy.php b/src/Fortify/Policies/Policy.php deleted file mode 100644 index 90e242bdf..000000000 --- a/src/Fortify/Policies/Policy.php +++ /dev/null @@ -1,14 +0,0 @@ -isSuperAdmin($user); - } - - public function view($user, Role $role) - { - return $this->isSuperAdmin($user); - } - - public function create($user) - { - return $this->isSuperAdmin($user); - } - - public function update($user, Role $role) - { - return $this->isSuperAdmin($user); - } - - public function delete($user, Role $role) - { - return $this->isSuperAdmin($user); - } - - public function restore($user, Role $role) - { - return $this->isSuperAdmin($user); - } - - public function forceDelete($user, Role $role) - { - return $this->isSuperAdmin($user); - } - - private function isSuperAdmin($user): bool - { - return $user->hasRole([ - app(UserRole::class)::SUPER_ADMIN, - ]); - } -} diff --git a/src/Fortify/Policies/UserPolicy.php b/src/Fortify/Policies/UserPolicy.php deleted file mode 100644 index 0c6c77b17..000000000 --- a/src/Fortify/Policies/UserPolicy.php +++ /dev/null @@ -1,28 +0,0 @@ -id === $model->id) { - return false; - } - - return $this->hasPermissionTo($user, 'delete'); - } - - public function create($user): bool - { - return false; - } -} diff --git a/src/Fortify/Responses/FailedTwoFactorLoginResponse.php b/src/Fortify/Responses/FailedTwoFactorLoginResponse.php deleted file mode 100644 index 8cbeee1df..000000000 --- a/src/Fortify/Responses/FailedTwoFactorLoginResponse.php +++ /dev/null @@ -1,38 +0,0 @@ -only(['code', 'recovery_code'])) - ->filter() - ->map(fn () => $message) - ->all(); - - if ($request->wantsJson()) { - throw ValidationException::withMessages($params); - } - - $request->session()->put([ - 'login.id' => $request->session()->get('login.idFailure'), - ]); - - return back()->withErrors($params); - } -} diff --git a/src/Fortify/Responses/RegisterResponse.php b/src/Fortify/Responses/RegisterResponse.php deleted file mode 100644 index f20b6630b..000000000 --- a/src/Fortify/Responses/RegisterResponse.php +++ /dev/null @@ -1,47 +0,0 @@ -wantsJson()) { - return new JsonResponse('', 201); - } - - if (config('fortify.accept_invitation_route')) { - $invitationId = $request->get('invitation'); - if ($invitationId) { - $invitation = Models::invitation()::findByUuid($invitationId); - if ($invitation->user()->is($request->user())) { - $urlGenerator = app(UrlGenerator::class); - $url = $urlGenerator->route(config('fortify.accept_invitation_route'), $invitation); - - return redirect()->to($url); - } - } - } - - if ($request->user() instanceof MustVerifyEmail) { - return redirect()->route('verification.notice'); - } - - return redirect('/'); - } -} diff --git a/src/Fortify/Responses/TwoFactorLoginResponse.php b/src/Fortify/Responses/TwoFactorLoginResponse.php deleted file mode 100644 index 3ec504bfd..000000000 --- a/src/Fortify/Responses/TwoFactorLoginResponse.php +++ /dev/null @@ -1,27 +0,0 @@ -wantsJson()) { - return new JsonResponse('', 204); - } - - if ($request->session()->has('url.intended')) { - return redirect($request->session()->pull('url.intended')); - } - - return redirect(config('fortify.home')); - } -} diff --git a/src/Fortify/Rules/Concerns/BaseRule.php b/src/Fortify/Rules/Concerns/BaseRule.php deleted file mode 100644 index c87d119a9..000000000 --- a/src/Fortify/Rules/Concerns/BaseRule.php +++ /dev/null @@ -1,12 +0,0 @@ -withForbiddenChars($value)) { - $this->withForbiddenChars = true; - - return false; - } - - if ($this->withRepetitiveSpecialChars($value)) { - $this->withRepetitiveSpecialChars = true; - - return false; - } - - if ($this->withReservedName($attribute, $value)) { - $this->withReservedName = true; - - return false; - } - - return true; - } - - /** - * Get the validation error message. - * - * @return string - */ - public function message(): string - { - if ($this->withReservedName) { - return ReservedUsername::message(); - } - - if ($this->withRepetitiveSpecialChars) { - return trans('ui::validation.messages.some_special_characters'); - } - - return trans('ui::validation.messages.some_special_characters'); - } - - public function withForbiddenChars(string $value): bool - { - // Some (unicode letter or number and . , - ' ’ & - return preg_match('/^[\p{L}\p{N}\p{Mn} .,\-\'’&]+$/u', $value) === 0; - } - - public function withRepetitiveSpecialChars(string $value): bool - { - return preg_match('/([.,\-\'’&])\1/u', $value) === 1; - } - - private function withReservedName($attribute, $value): bool - { - return ! ReservedUsername::passes($attribute, $value); - } -} diff --git a/src/Fortify/Rules/OneLetter.php b/src/Fortify/Rules/OneLetter.php deleted file mode 100644 index a34922384..000000000 --- a/src/Fortify/Rules/OneLetter.php +++ /dev/null @@ -1,36 +0,0 @@ - 0; - } - - /** - * Get the validation error message. - * - * @return string - */ - public function message() - { - return trans('ui::validation.messages.include_letters'); - } -} diff --git a/src/Fortify/Rules/OneTimePassword.php b/src/Fortify/Rules/OneTimePassword.php deleted file mode 100644 index 6f4726454..000000000 --- a/src/Fortify/Rules/OneTimePassword.php +++ /dev/null @@ -1,32 +0,0 @@ -secret = $secret; - } - - public function passes($attribute, $value) - { - try { - return Google2FA::verifyKey($this->secret, $value); - } catch (\Throwable $th) { - return false; - } - } - - public function message() - { - return trans('ui::validation.messages.one_time_password'); - } -} diff --git a/src/Fortify/Rules/StartsWithLetterOrNumber.php b/src/Fortify/Rules/StartsWithLetterOrNumber.php deleted file mode 100644 index bf81b7292..000000000 --- a/src/Fortify/Rules/StartsWithLetterOrNumber.php +++ /dev/null @@ -1,36 +0,0 @@ - 0; - } - - /** - * Get the validation error message. - * - * @return string - */ - public function message() - { - return trans('ui::validation.messages.start_with_letter_or_number'); - } -} diff --git a/src/Fortify/Rules/Username.php b/src/Fortify/Rules/Username.php deleted file mode 100644 index 61fcf3ce6..000000000 --- a/src/Fortify/Rules/Username.php +++ /dev/null @@ -1,198 +0,0 @@ -withForbiddenSpecialChars($value)) { - $this->withForbiddenSpecialChars = true; - - return false; - } - - if ($this->withSpecialCharAtTheStart($value)) { - $this->withSpecialCharAtTheStart = true; - - return false; - } - - if ($this->withSpecialCharAtTheEnd($value)) { - $this->withSpecialCharAtTheEnd = true; - - return false; - } - - if ($this->withConsecutiveSpecialChars($value)) { - $this->withConsecutiveSpecialChars = true; - - return false; - } - - if ($this->needsMaximumLength($value)) { - $this->hasReachedMaxLength = true; - - return false; - } - - if ($this->needsLowercase($value)) { - $this->hasUpperCaseCharacters = true; - - return false; - } - - if ($this->withReservedName($attribute, $value)) { - $this->withReservedName = true; - - return false; - } - - return ! $this->needsMinimumLength($value); - } - - /** - * Get the validation error message. - * - * @return string - */ - public function message(): string - { - switch (true) { - case $this->withSpecialCharAtTheStart: - return trans('ui::validation.messages.username.special_character_start'); - - case $this->withSpecialCharAtTheEnd: - return trans('ui::validation.messages.username.special_character_end'); - - case $this->withConsecutiveSpecialChars: - return trans('ui::validation.messages.username.consecutive_special_characters'); - - case $this->withForbiddenSpecialChars: - return trans('ui::validation.messages.username.forbidden_special_characters'); - - case $this->hasReachedMaxLength: - return trans('ui::validation.messages.username.max_length', [ - 'length' => Constants::MAX_USERNAME_CHARACTERS, - ]); - - case $this->hasUpperCaseCharacters: - return trans('ui::validation.messages.username.lowercase_only'); - - case $this->withReservedName: - return ReservedUsername::message(); - - default: - return trans('ui::validation.messages.username.min_length', [ - 'length' => Constants::MIN_USERNAME_CHARACTERS, - ]); - } - } - - public function withForbiddenSpecialChars(string $value): bool - { - return preg_match('/[^\w.]/', $value) === 1; - } - - public function withSpecialCharAtTheStart(string $value): bool - { - return preg_match('/^\W|^[_|\.]/', $value) === 1; - } - - public function withSpecialCharAtTheEnd(string $value): bool - { - return preg_match('/\W$|[_|\.]$/', $value) === 1; - } - - public function withConsecutiveSpecialChars(string $value): bool - { - return preg_match('/^[^a-zA-Z0-9]?(?>[a-zA-Z0-9]+[^a-zA-Z0-9])*[a-zA-Z0-9]*$/', $value) === 0; - } - - public function needsMinimumLength(string $value): bool - { - return Str::length($value) < Constants::MIN_USERNAME_CHARACTERS; - } - - public function needsMaximumLength(string $value): bool - { - return Str::length($value) > Constants::MAX_USERNAME_CHARACTERS; - } - - public function needsLowercase(string $value): bool - { - return $value !== strtolower($value); - } - - protected function withReservedName(string $attribute, mixed $value): bool - { - return ! ReservedUsername::passes($attribute, $value); - } -} diff --git a/src/Fortify/Support/Enums/Constants.php b/src/Fortify/Support/Enums/Constants.php deleted file mode 100644 index 3986cc3de..000000000 --- a/src/Fortify/Support/Enums/Constants.php +++ /dev/null @@ -1,16 +0,0 @@ - $actions) { - foreach ($actions as $action) { - $permissions[$role][] = "{$action} {$resource}"; - } - } - } - - return $permissions; - } - - public static function mapToRoles(): void - { - $permissionMapping = static::all(); - $permissions = Permission::all()->keyBy('name'); - - foreach (Role::all() as $role) { - /** @var \stdClass $role */ - if (! array_key_exists($role->name, $permissionMapping)) { - continue; - } - - $toInsert = collect(); - if ($role->name === app(UserRole::class)::SUPER_ADMIN) { - $toInsert = $permissions; - } else { - $toInsert = $permissions->whereIn('name', $permissionMapping[$role->name]); - } - - DB::table('role_has_permissions')->insert(collect($toInsert)->map(fn ($permission) => [ - 'role_id' => $role->id, - 'permission_id' => $permission->id, - ])->toArray()); - } - } -} diff --git a/src/Fortify/Support/Services/PermissionRegistrar.php b/src/Fortify/Support/Services/PermissionRegistrar.php deleted file mode 100644 index eb0d24c04..000000000 --- a/src/Fortify/Support/Services/PermissionRegistrar.php +++ /dev/null @@ -1,41 +0,0 @@ -getPermissionClass(); - - $query = $permission->with('roles'); - - foreach ($params as $attr => $value) { - $query->where((string) $attr, $value); - } - - if ($onlyOne) { - $query->limit(1); - } - - return $query->get(); - }); - } -} diff --git a/src/Hermes/Components/ManageNotifications.php b/src/Hermes/Components/ManageNotifications.php index 848381ebc..ba4759f19 100644 --- a/src/Hermes/Components/ManageNotifications.php +++ b/src/Hermes/Components/ManageNotifications.php @@ -4,7 +4,7 @@ namespace ARKEcosystem\Foundation\Hermes\Components; -use ARKEcosystem\Foundation\Fortify\Components\Concerns\InteractsWithUser; +use ARKEcosystem\Foundation\Blog\Components\Concerns\InteractsWithUser; use ARKEcosystem\Foundation\Hermes\Enums\NotificationFilterEnum; use Illuminate\Contracts\View\View; use Illuminate\Notifications\DatabaseNotification; diff --git a/src/Hermes/Models/DatabaseNotification.php b/src/Hermes/Models/DatabaseNotification.php index def213243..eec0ba29c 100644 --- a/src/Hermes/Models/DatabaseNotification.php +++ b/src/Hermes/Models/DatabaseNotification.php @@ -4,7 +4,7 @@ namespace ARKEcosystem\Foundation\Hermes\Models; -use ARKEcosystem\Foundation\Fortify\Models\Concerns\HasLocalizedTimestamps; +use ARKEcosystem\Foundation\Blog\Models\Concerns\HasLocalizedTimestamps; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\MorphTo; use Illuminate\Notifications\DatabaseNotification as BaseNotification; diff --git a/src/Providers/FortifyServiceProvider.php b/src/Providers/FortifyServiceProvider.php deleted file mode 100644 index 3ed028be0..000000000 --- a/src/Providers/FortifyServiceProvider.php +++ /dev/null @@ -1,292 +0,0 @@ -registerResponseBindings(); - } - - /** - * Bootstrap any application services. - * - * @return void - */ - public function boot() - { - $this->registerPublishers(); - - $this->registerLivewireComponents(); - - $this->registerActions(); - - $this->registerViews(); - - $this->registerAuthentication(); - - $this->registerRoutes(); - - $this->registerCommands(); - - $this->registerContracts(); - } - - /** - * Register the publishers. - * - * @return void - */ - public function registerPublishers(): void - { - $this->publishes([ - __DIR__.'/../../config/fortify.php' => config_path('fortify.php'), - ], 'config'); - - $this->mergeConfigFrom( - __DIR__.'/../../config/newsletter.php', - 'newsletter' - ); - - $this->mergeConfigFrom( - __DIR__.'/../../config/fortify.php', - 'fortify' - ); - - $this->publishes([ - __DIR__.'/../../resources/views/auth' => resource_path('views/auth'), - __DIR__.'/../../resources/views/components' => resource_path('views/components'), - __DIR__.'/../../resources/views/profile' => resource_path('views/profile'), - __DIR__.'/../../resources/views/account' => resource_path('views/account'), - ], 'foundation-views'); - - $this->publishes([ - __DIR__.'/../../resources/images' => resource_path('images'), - ], 'images'); - } - - /** - * Register the Livewire components. - * - * @return void - */ - public function registerLivewireComponents(): void - { - Livewire::component('profile.delete-user-form', DeleteUserForm::class); - Livewire::component('profile.export-user-data', ExportUserData::class); - Livewire::component('profile.logout-other-browser-sessions-form', LogoutOtherBrowserSessionsForm::class); - Livewire::component('profile.two-factor-authentication-form', TwoFactorAuthenticationForm::class); - Livewire::component('profile.update-password-form', UpdatePasswordForm::class); - Livewire::component('profile.update-profile-information-form', UpdateProfileInformationForm::class); - Livewire::component('profile.update-profile-photo-form', UpdateProfilePhotoForm::class); - Livewire::component('profile.update-timezone-form', UpdateTimezoneForm::class); - Livewire::component('auth.register-form', RegisterForm::class); - Livewire::component('auth.reset-password-form', ResetPasswordForm::class); - Livewire::component('newsletter.footer-subscription-form', FooterEmailSubscriptionForm::class); - Livewire::component('auth.verify-email', VerifyEmail::class); - } - - /** - * Register the actions. - * - * @return void - */ - public function registerActions(): void - { - Fortify::createUsersUsing(CreateNewUser::class); - Fortify::updateUserProfileInformationUsing(UpdateUserProfileInformation::class); - Fortify::updateUserPasswordsUsing(UpdateUserPassword::class); - Fortify::resetUserPasswordsUsing(ResetUserPassword::class); - - app()->singleton(DeleteUserContract::class, DeleteUser::class); - } - - public function registerRoutes(): void - { - Route::middleware('web')->group(function () { - Route::view(config('fortify.routes.feedback_thank_you'), 'ark-fortify::profile.feedback-thank-you') - ->name('profile.feedback.thank-you') - ->middleware('signed'); - - Route::get(config('fortify.routes.two_factor_reset_password'), [TwoFactorAuthenticatedPasswordResetController::class, 'create']) - ->name('two-factor.reset-password') - ->middleware('guest'); - - Route::post(config('fortify.routes.two_factor_reset_password'), [TwoFactorAuthenticatedPasswordResetController::class, 'store']) - ->name('two-factor.reset-password-store') - ->middleware('guest'); - }); - - if (Features::enabled(Features::updateProfileInformation())) { - Route::group(['middleware' => config('fortify.middlewares.account_settings.update_profile', ['web', 'auth'])], function () { - Route::view(config('fortify.routes.account_settings_account'), 'ark-fortify::account.settings-account') - ->name('account.settings.account'); - }); - } - - if (Features::enabled(Features::updatePasswords())) { - Route::group(['middleware' => config('fortify.middlewares.account_settings.update_password', ['web', 'auth'])], function () { - $slug = (string) config('fortify.routes.account_settings_password'); - - Route::view($slug, 'ark-fortify::account.settings-password')->name('account.settings.password'); - Route::redirect('/.well-known/change-password', $slug); - }); - } - } - - /** - * Register the views. - * - * @return void - */ - private function registerViews(): void - { - $this->loadViewsFrom(__DIR__.'/../../resources/views', 'ark-fortify'); - - Fortify::loginView(function () { - return view('ark-fortify::auth.login'); - }); - - Fortify::twoFactorChallengeView(function ($request) { - $request->session()->put([ - 'login.idFailure' => $request->session()->get('login.id'), - ]); - - return view('ark-fortify::auth.two-factor-challenge'); - }); - - Fortify::registerView(function ($request) { - return view('ark-fortify::auth.register'); - }); - - Fortify::requestPasswordResetLinkView(function () { - return view('ark-fortify::auth.forgot-password'); - }); - - Fortify::resetPasswordView(function ($request) { - $user = Models::user()::where('email', $request->get('email'))->firstOrFail(); - - if ($user->two_factor_secret) { - return redirect()->route('two-factor.reset-password', ['token' => $request->token, 'email' => $user->email]); - } - - return view('ark-fortify::auth.reset-password', ['request' => $request]); - }); - - Fortify::verifyEmailView(function () { - return view('ark-fortify::auth.verify-email'); - }); - - Fortify::confirmPasswordView(function () { - return view('ark-fortify::auth.confirm-password'); - }); - } - - /** - * Register the authentication callbacks. - * - * @return void - */ - private function registerAuthentication(): void - { - Fortify::authenticateUsing(function (Request $request) { - return (new AuthenticateUser($request))->handle(); - }); - } - - /** - * Register the response bindings. - * - * @return void - */ - private function registerResponseBindings() - { - $this->app->singleton( - RegisterResponseContract::class, - RegisterResponse::class - ); - - $this->app->singleton( - FailedTwoFactorLoginResponseContract::class, - FailedTwoFactorLoginResponse::class - ); - - $this->app->singleton( - TwoFactorLoginResponseContract::class, - TwoFactorLoginResponse::class - ); - - $this->app->singleton( - FailedPasswordResetLinkRequestResponse::class, - FortifyFailedPasswordResetLinkRequestResponse::class - ); - - $this->app->singleton( - SuccessfulPasswordResetLinkRequestResponse::class, - FortifySuccessfulPasswordResetLinkRequestResponse::class - ); - } - - private function registerCommands() - { - $this->commands([ - CreateUserCommand::class, - RunPlaybookCommand::class, - ]); - } - - private function registerContracts() - { - $this->app->singleton(UserRoleContract::class, UserRole::class); - } -} diff --git a/src/Providers/FoundationServiceProvider.php b/src/Providers/FoundationServiceProvider.php index 8aa353ed0..8dd8bb75b 100644 --- a/src/Providers/FoundationServiceProvider.php +++ b/src/Providers/FoundationServiceProvider.php @@ -24,13 +24,8 @@ public function register() $this->app->register(StanServiceProvider::class); $this->app->register(CommonMarkServiceProvider::class); $this->app->register(HermesServiceProvider::class); - $this->app->register(FortifyServiceProvider::class); $this->app->register(RulesServiceProvider::class); $this->app->register(UserInterfaceServiceProvider::class); $this->app->register(StringMacroServiceProvider::class); - - if (class_exists('\Laravel\Nova\Nova')) { - $this->app->register(NovaServiceProvider::class); - } } } diff --git a/src/Providers/NovaServiceProvider.php b/src/Providers/NovaServiceProvider.php deleted file mode 100644 index 461d473ef..000000000 --- a/src/Providers/NovaServiceProvider.php +++ /dev/null @@ -1,114 +0,0 @@ -in($directory)->files() as $file) { - /** @var string $resource */ - $resource = 'App\\Nova\\'.ucfirst(Str::replaceLast('.php', '', $file->getRelativePathname())); - - if (is_subclass_of($resource, Resource::class) && - ! (new ReflectionClass($resource))->isAbstract() && - ! (is_subclass_of($resource, ActionResource::class))) { - $resources[] = $resource; - } - } - - Nova::resources(collect($resources)->sort()->all()); - } - - /** - * Register the Nova routes. - * - * @return void - */ - protected function routes(): void - { - Route::namespace('Laravel\Nova\Http\Controllers') - ->domain(config('nova.domain', null)) - ->middleware(config('nova.middleware', [])) - ->prefix(Nova::path()) - ->group(fn () => Route::get('/logout', 'LoginController@logout')->name('nova.logout')); - - Nova::routes()->register(); - } - - /** - * Register the Nova gate. - * - * This gate determines who can access Nova in non-local environments. - * - * @return void - */ - protected function gate(): void - { - Gate::define('viewNova', fn ($user): bool => $user->canModerate()); - } - - /** - * Get the cards that should be displayed on the default Nova dashboard. - * - * @return array - */ - protected function cards(): array - { - return []; - } - - /** - * Get the extra dashboards that should be displayed on the Nova dashboard. - * - * @return array - */ - protected function dashboards(): array - { - return []; - } - - /** - * Register the application's Nova resources. - * - * @return void - */ - protected function resources() - { - self::resourcesIn(app_path('Nova')); - - // TODO: enable when https://github.com/vyuldashev/nova-permission merges in support for Nova v4... - if (! str_starts_with(Nova::version(), '4.')) { - Nova::resources([ - NovaPermission::class, - NovaRole::class, - ]); - } - } -} diff --git a/tests/Blog/TestCase.php b/tests/Blog/TestCase.php index deb409479..50774cf2f 100644 --- a/tests/Blog/TestCase.php +++ b/tests/Blog/TestCase.php @@ -5,10 +5,11 @@ namespace Tests\Blog; use ARKEcosystem\Foundation\Blog\Enums\Category; -use ARKEcosystem\Foundation\Fortify\Http\Middleware\EnforceTwoFactorAuthentication; +use ARKEcosystem\Foundation\Blog\Http\Middleware\EnforceTwoFactorAuthentication; use ARKEcosystem\Foundation\Providers\BlogServiceProvider; use ARKEcosystem\Foundation\Providers\MarkdownServiceProvider; use ARKEcosystem\Foundation\Providers\UserInterfaceServiceProvider; +use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\View; use JamesMills\LaravelTimezone\LaravelTimezoneServiceProvider; use Livewire\LivewireServiceProvider; @@ -22,11 +23,14 @@ */ class TestCase extends Base { + use RefreshDatabase; + protected function setUp(): void { parent::setUp(); $this->withoutVite(); + $this->loadMigrationsFrom(dirname(__DIR__).'/database/migrations'); $this->loadMigrationsFrom(__DIR__.'/database/migrations'); } @@ -63,4 +67,10 @@ protected function getPackageAliases($app) 'BlogCategory' => Category::class, ]; } + + protected function afterRefreshingDatabase() + { + $this->loadMigrationsFrom(dirname(__DIR__).'/database/migrations'); + $this->loadMigrationsFrom(__DIR__.'/database/migrations'); + } } diff --git a/tests/Fortify/Actions/AuthenticateUserTest.php b/tests/Fortify/Actions/AuthenticateUserTest.php deleted file mode 100644 index 03af63def..000000000 --- a/tests/Fortify/Actions/AuthenticateUserTest.php +++ /dev/null @@ -1,174 +0,0 @@ -create(); - - $request = new Request(); - - $request->replace([ - 'email' => $user->email, - 'password' => 'password', - ]); - - $authenticator = new AuthenticateUser($request); - $loggedUser = $authenticator->handle(); - - $this->assertNotNull($loggedUser); - $this->assertTrue($user->is($loggedUser)); - $this->assertFalse($request->filled('remember')); -}); - -it('login the user with case insensitive email', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - - $user = User::factory()->create(); - - $request = new Request(); - - $request->replace([ - 'email' => strtoupper($user->email), - 'password' => 'password', - ]); - - $authenticator = new AuthenticateUser($request); - $loggedUser = $authenticator->handle(); - - $this->assertNotNull($loggedUser); - $this->assertTrue($user->is($loggedUser)); - $this->assertFalse($request->filled('remember')); -}); - -it('login the user by the email when alt username is set', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - Config::set('fortify.username_alt', 'username'); - - $user = User::factory()->withUsername()->create(); - - $request = new Request(); - - $request->replace([ - 'email' => $user->email, - 'password' => 'password', - ]); - - $authenticator = new AuthenticateUser($request); - $loggedUser = $authenticator->handle(); - - $this->assertNotNull($loggedUser); - $this->assertTrue($user->is($loggedUser)); - $this->assertFalse($request->filled('remember')); -}); - -it('login the user by the alt username (username)', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - Config::set('fortify.username_alt', 'username'); - - $user = User::factory()->withUsername()->create(); - - $request = new Request(); - - $request->replace([ - 'email' => $user->username, - 'password' => 'password', - ]); - - $authenticator = new AuthenticateUser($request); - $loggedUser = $authenticator->handle(); - - $this->assertNotNull($loggedUser); - $this->assertTrue($user->is($loggedUser)); - $this->assertFalse($request->filled('remember')); -}); - -it('login the user with case insensitive alt username', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - Config::set('fortify.username_alt', 'username'); - - $user = User::factory()->withUsername()->create(); - - $request = new Request(); - - $request->replace([ - 'email' => strtoupper($user->username), - 'password' => 'password', - ]); - - $authenticator = new AuthenticateUser($request); - $loggedUser = $authenticator->handle(); - - $this->assertNotNull($loggedUser); - $this->assertTrue($user->is($loggedUser)); - $this->assertFalse($request->filled('remember')); -}); - -it('doesnt login the user by the alt username if not set (username)', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - Config::set('fortify.username_alt', null); - - $user = User::factory()->withUsername()->create(); - - $request = new Request(); - - $request->replace([ - 'email' => $user->username, - 'password' => 'password', - ]); - - $authenticator = new AuthenticateUser($request); - $loggedUser = $authenticator->handle(); - - $this->assertNull($loggedUser); - $this->assertFalse($request->filled('remember')); -}); - -it('doesnt login the user if password is incorrect', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - - $user = User::factory()->create(); - - $request = new Request(); - - $request->replace([ - 'email' => $user->email, - 'password' => 'wrong-password', - ]); - - $authenticator = new AuthenticateUser($request); - $loggedUser = $authenticator->handle(); - - $this->assertNull($loggedUser); -}); - -it('should handle the remember me checkbox', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - Config::set('fortify.username_alt', 'username'); - - $user = User::factory()->withUsername()->create(); - - $request = new Request(); - - $this->assertFalse($request->filled('remember')); - - $request->replace([ - 'email' => $user->username, - 'password' => 'password', - 'remember' => true, - ]); - - $authenticator = new AuthenticateUser($request); - $loggedUser = $authenticator->handle(); - - $this->assertNotNull($loggedUser); - $this->assertTrue($user->is($loggedUser)); - - $this->assertTrue($request->filled('remember')); -}); diff --git a/tests/Fortify/Actions/CreateNewUserTest.php b/tests/Fortify/Actions/CreateNewUserTest.php deleted file mode 100644 index 972daf8f3..000000000 --- a/tests/Fortify/Actions/CreateNewUserTest.php +++ /dev/null @@ -1,312 +0,0 @@ -validPassword = 'Pas3w05d&123456'; - - $this->mock(UncompromisedVerifier::class)->shouldReceive('verify')->andReturn(true); -}); - -it('should create a valid user with the create user action', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - - $user = (new CreateNewUser())->create([ - 'name' => 'John Doe', - 'username' => 'alfonsobries', - 'email' => 'john@doe.com', - 'password' => $this->validPassword, - 'password_confirmation' => $this->validPassword, - 'terms' => true, - ]); - - $this->assertSame('john@doe.com', $user->email); - $this->assertSame('John Doe', $user->name); - $this->assertTrue(Hash::check($this->validPassword, $user->password)); -}); - -it('should create user and force lowercase email', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - - $user = (new CreateNewUser())->create([ - 'name' => 'John Doe', - 'username' => 'alfonsobries', - 'email' => 'JOHN@DOE.COM', - 'password' => $this->validPassword, - 'password_confirmation' => $this->validPassword, - 'terms' => true, - ]); - - $this->assertSame('john@doe.com', $user->email); - $this->assertSame('John Doe', $user->name); - $this->assertTrue(Hash::check($this->validPassword, $user->password)); -}); - -it('should not create user with uppercase characters', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - - expectValidationError(fn () => (new CreateNewUser())->create([ - 'name' => 'John Doe', - 'username' => 'JOHNDOE', - 'email' => 'john@doe.com', - 'password' => 'sec$r2t12345', - 'password_confirmation' => 'sec$r2t12345', - 'terms' => true, - ]), 'username', trans('ui::validation.messages.username.lowercase_only')); -}); - -it('should create a valid user with username if the username_alt setting is set', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - Config::set('fortify.username_alt', 'username'); - - $user = (new CreateNewUser())->create([ - 'name' => 'John Doe', - 'username' => 'alfonsobries', - 'email' => 'john@doe.com', - 'password' => $this->validPassword, - 'password_confirmation' => $this->validPassword, - 'terms' => true, - ]); - - $this->assertSame('john@doe.com', $user->email); - $this->assertSame('alfonsobries', $user->username); - $this->assertSame('John Doe', $user->name); - $this->assertTrue(Hash::check($this->validPassword, $user->password)); -}); - -it('should require a username if alt username is set', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - - Config::set('fortify.username_alt', 'username'); - - expectValidationError(fn () => (new CreateNewUser())->create([ - 'name' => 'John Doe', - 'email' => 'john@doe.com', - 'password' => $this->validPassword, - 'password_confirmation' => $this->validPassword, - 'terms' => true, - ]), 'username', 'The username field is required.'); -}); - -it('should require an email', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - - expectValidationError(fn () => (new CreateNewUser())->create([ - 'name' => 'John Doe', - 'username' => 'alfonsobries', - 'email' => '', - 'password' => $this->validPassword, - 'password_confirmation' => $this->validPassword, - 'terms' => true, - ]), 'email', 'The email field is required.'); -}); - -it('should require a valid email', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - - expectValidationError(fn () => (new CreateNewUser())->create([ - 'name' => 'John Doe', - 'username' => 'alfonsobries', - 'email' => 'alfonsobries', - 'password' => $this->validPassword, - 'password_confirmation' => $this->validPassword, - 'terms' => true, - ]), 'email', 'The email field must be a valid email address.'); -}); - -it('should require the terms to be accepted', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - - expectValidationError(fn () => (new CreateNewUser())->create([ - 'name' => 'John Doe', - 'username' => 'alfonsobries', - 'email' => 'john@doe.com', - 'password' => $this->validPassword, - 'password_confirmation' => $this->validPassword, - 'terms' => false, - ]), 'terms', 'The terms field must be accepted.'); -}); - -it('password should match the confirmation', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - - expectValidationError(fn () => (new CreateNewUser())->create([ - 'name' => 'John Doe', - 'username' => 'alfonsobries', - 'email' => 'john@doe.com', - 'password' => $this->validPassword, - 'password_confirmation' => 'password', - 'terms' => true, - ]), 'password_confirmation', 'The password confirmation field must match password.'); -}); - -it('password should be equal to or longer than 12 characters', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - - expectValidationError(fn () => (new CreateNewUser())->create([ - 'name' => 'John Doe', - 'username' => 'alfonsobries', - 'email' => 'john@doe.com', - 'password' => 'Sec$r2t', - 'password_confirmation' => 'Sec$r2t', - 'terms' => true, - ]), 'password', 'The password field must be at least 12 characters.'); -}); - -it('password should require an uppercase letter', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - - expectValidationError(fn () => (new CreateNewUser())->create([ - 'name' => 'John Doe', - 'username' => 'alfonsobries', - 'email' => 'john@doe.com', - 'password' => 'sec$r2t12345', - 'password_confirmation' => 'sec$r2t12345', - 'terms' => true, - ]), 'password', 'The password field must contain at least one uppercase and one lowercase letter.'); -}); - -it('password should require one number', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - - expectValidationError(fn () => (new CreateNewUser())->create([ - 'name' => 'John Doe', - 'username' => 'alfonsobries', - 'email' => 'john@doe.com', - 'password' => 'sec$%Asfhhdfhfdhgd', - 'password_confirmation' => 'sec$%Asfhhdfhfdhgd', - 'terms' => true, - ]), 'password', 'The password field must contain at least one number.'); -}); - -it('password should require one special character', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - - expectValidationError(fn () => (new CreateNewUser())->create([ - 'name' => 'John Doe', - 'username' => 'alfonsobries', - 'email' => 'john@doe.com', - 'password' => 'sec23Asfhhdfhfdhgd', - 'password_confirmation' => 'sec23Asfhhdfhfdhgd', - 'terms' => true, - ]), 'password', 'The password field must contain at least one symbol.'); -}); - -it('handles the invitation parameter', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - Config::set('fortify.models.invitation', TestUser::class); - - $user = (new CreateNewUser())->create([ - 'name' => 'John Doe', - 'username' => 'alfonsobries', - 'email' => 'john@doe.com', - 'password' => $this->validPassword, - 'password_confirmation' => $this->validPassword, - 'terms' => true, - 'invitation' => 'uuid-uuid-uuid-uuid', - ]); - - $invitation = Models::invitation()::findByUuid('uuid-uuid-uuid-uuid'); - - $this->assertSame($user->id, $invitation->user_id); -}); - -it('does not mark the user email as verified if it has an invitation', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - Config::set('fortify.models.invitation', TestUser::class); - - $user = (new CreateNewUser())->create([ - 'name' => 'John Doe', - 'username' => 'alfonsobries', - 'email' => 'john@doe.com', - 'password' => $this->validPassword, - 'password_confirmation' => $this->validPassword, - 'terms' => true, - 'invitation' => 'uuid-uuid-uuid-uuid', - ]); - - $this->assertNull($user->email_verified_at); -}); - -it('does not mark the user email as verified if it has no invitation ', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - - $user = (new CreateNewUser())->create([ - 'name' => 'John Doe', - 'username' => 'alfonsobries', - 'email' => 'john@doe.com', - 'password' => $this->validPassword, - 'password_confirmation' => $this->validPassword, - 'terms' => true, - ]); - - $this->assertNull($user->email_verified_at); -}); - -it('should require to have a properly formatted username', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - - expectValidationError(fn () => (new CreateNewUser())->create([ - 'name' => 'John Doe', - 'username' => '_johndoe', - 'email' => 'john@doe.com', - 'password' => 'sec$r2t12345', - 'password_confirmation' => 'sec$r2t12345', - 'terms' => true, - ]), 'username', trans('ui::validation.messages.username.special_character_start')); -}); - -it('should validate username correctly if it is the primary username field', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - Config::set('fortify.username', 'username'); - Config::set('fortify.username_alt', 'email'); - - expectValidationError(fn () => (new CreateNewUser())->create([ - 'name' => 'John Doe', - 'username' => '_johndoe', - 'email' => 'john@doe.com', - 'password' => 'sec$r2t12345', - 'password_confirmation' => 'sec$r2t12345', - 'terms' => true, - ]), 'username', trans('ui::validation.messages.username.special_character_start')); -}); - -it('should work with username authentication', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - Config::set('fortify.username_alt', 'username'); - - $user = (new CreateNewUser())->create([ - 'name' => 'John Doe', - 'username' => 'alfonsobries', - 'email' => 'john@doe.com', - 'password' => $this->validPassword, - 'password_confirmation' => $this->validPassword, - 'terms' => true, - ]); - - $this->assertSame('john@doe.com', $user->email); - $this->assertSame('John Doe', $user->name); - $this->assertTrue(Hash::check($this->validPassword, $user->password)); -}); - -it('should validate correctly with alt username set to email', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - Config::set('fortify.username_alt', 'email'); - - expect(fn () => (new CreateNewUser())->create([ - 'name' => 'John Doe', - 'username' => 'alfonsobries', - 'email' => 'johndoe.com', - 'password' => $this->validPassword, - 'password_confirmation' => $this->validPassword, - 'terms' => true, - ]))->toThrow('The email field must be a valid email address.'); -}); diff --git a/tests/Fortify/Actions/DeleteUserTest.php b/tests/Fortify/Actions/DeleteUserTest.php deleted file mode 100644 index 0d9066268..000000000 --- a/tests/Fortify/Actions/DeleteUserTest.php +++ /dev/null @@ -1,21 +0,0 @@ - 'John Doe', - 'username' => 'johndoe', - 'email' => 'john@doe.com', - 'password' => 'password', - ]); - - expect(User::find($user->id)->id)->toBe($user->id); - - (new DeleteUser())->delete($user); - - expect(User::find($user->id))->toBeNull(); -}); diff --git a/tests/Fortify/Actions/EnableTwoFactorAuthenticationTest.php b/tests/Fortify/Actions/EnableTwoFactorAuthenticationTest.php deleted file mode 100644 index 8e951d9d2..000000000 --- a/tests/Fortify/Actions/EnableTwoFactorAuthenticationTest.php +++ /dev/null @@ -1,18 +0,0 @@ -two_factor_secret)->toBeNull(); - expect($user->two_factor_recovery_codes)->toBeNull(); - - resolve(EnableTwoFactorAuthentication::class)($user, 'secretKey'); - - expect($user->two_factor_secret)->not()->toBeNull(); - expect($user->two_factor_recovery_codes)->not()->toBeNull(); -}); diff --git a/tests/Fortify/Actions/GenerateTwoFactorAuthenticationSecretKeyTest.php b/tests/Fortify/Actions/GenerateTwoFactorAuthenticationSecretKeyTest.php deleted file mode 100644 index 3e347883d..000000000 --- a/tests/Fortify/Actions/GenerateTwoFactorAuthenticationSecretKeyTest.php +++ /dev/null @@ -1,11 +0,0 @@ -toBeString(); -}); diff --git a/tests/Fortify/Actions/ResetUserPasswordTest.php b/tests/Fortify/Actions/ResetUserPasswordTest.php deleted file mode 100644 index 94165b6de..000000000 --- a/tests/Fortify/Actions/ResetUserPasswordTest.php +++ /dev/null @@ -1,71 +0,0 @@ -mock(UncompromisedVerifier::class)->shouldReceive('verify')->andReturn(true); -}); - -it('should reset the user password', function () { - $user = createUserModel(); - - expect($user->password)->toBe('$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi'); - - resolve(ResetUserPassword::class)->reset($user, [ - 'password' => 'Pas3w05d&123456', - 'password_confirmation' => 'Pas3w05d&123456', - ]); - - expect($user->password)->not()->toBe('$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi'); -}); - -it('should throw an exception if the password is too short', function () { - $user = createUserModel(); - - expectValidationError(fn () => resolve(ResetUserPassword::class)->reset($user, [ - 'password' => 'pass', - ]), 'password', 'The password field must be at least 12 characters.'); -}); - -it('should throw an exception if the password is too weak', function () { - $user = createUserModel(); - - expectValidationError(fn () => resolve(ResetUserPassword::class)->reset($user, [ - 'password' => 'weak', - ]), 'password', 'The password field must be at least 12 characters.'); -}); - -it('should throw an exception if the password is not confirmed', function () { - $user = createUserModel(); - - expectValidationError(fn () => resolve(ResetUserPassword::class)->reset($user, [ - 'password' => 'Pas3w05d&123456', - 'password_confirmation' => null, - ]), 'password_confirmation', 'The password confirmation field must match password.'); -}); - -it('should throw an exception if the password confirmation does not match', function () { - $user = createUserModel(); - - expectValidationError(fn () => resolve(ResetUserPassword::class)->reset($user, [ - 'password' => 'Pas3w05d&123456', - 'password_confirmation' => 'password', - ]), 'password_confirmation', 'The password confirmation field must match password.'); -}); - -it('should throw an exception if the password is the same', function () { - $user = createUserModel(); - - $user->update(['password' => Hash::make('Pas3w05d&123456')]); - - expectValidationError(fn () => resolve(ResetUserPassword::class)->reset($user->fresh(), [ - 'password' => 'Pas3w05d&123456', - 'password_confirmation' => 'Pas3w05d&123456', - ]), 'password', 'You cannot use your existing password.'); -}); diff --git a/tests/Fortify/Actions/SubscribeToNewsletterTest.php b/tests/Fortify/Actions/SubscribeToNewsletterTest.php deleted file mode 100644 index c9b237d82..000000000 --- a/tests/Fortify/Actions/SubscribeToNewsletterTest.php +++ /dev/null @@ -1,47 +0,0 @@ - resolve(SubscribeToNewsletter::class)->execute('', 'subscribers'), - 'email', - 'The email field is required.' - ); -}); - -it('should validate email is invalid', function () { - expectValidationError( - fn () => resolve(SubscribeToNewsletter::class)->execute('invalid email', 'subscribers'), - 'email', - 'The email field must be a valid email address.' - ); -}); - -it('should validate list', function () { - expectValidationError( - fn () => resolve(SubscribeToNewsletter::class)->execute('email@email.com', 'test list'), - 'list', - 'The selected list is invalid.' - ); -}); - -it('should return false if not subscribed', function () { - Config::set('newsletter.apiKey', 'test-test'); - Config::set('newsletter.lists.subscribers.id', 'list-id'); - - Newsletter::shouldReceive('isSubscribed') - ->once() - ->andReturn(false); - - Newsletter::shouldReceive('subscribePending') - ->once() - ->andReturn(false); - - expect(resolve(SubscribeToNewsletter::class)->execute('email@email.com', 'subscribers'))->toBeFalse(); -}); diff --git a/tests/Fortify/Actions/UpdateUserPasswordTest.php b/tests/Fortify/Actions/UpdateUserPasswordTest.php deleted file mode 100644 index 84b9e648c..000000000 --- a/tests/Fortify/Actions/UpdateUserPasswordTest.php +++ /dev/null @@ -1,75 +0,0 @@ -mock(UncompromisedVerifier::class)->shouldReceive('verify')->andReturn(true); -}); - -it('should reset the user password', function () { - $user = createUserModel(); - - expect($user->password)->toBe('$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi'); - - resolve(UpdateUserPassword::class)->update($user, [ - 'current_password' => 'password', - 'password' => 'Pas3w05d&123456', - 'password_confirmation' => 'Pas3w05d&123456', - ]); - - expect($user->password)->not()->toBe('$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi'); -}); - -it('should throw an exception if the old password is missing', function () { - $user = createUserModel(); - - expectValidationError(fn () => resolve(UpdateUserPassword::class)->update($user, [ - 'current_password' => null, - 'password' => 'Pas3w05d&123456', - 'password_confirmation' => 'Pas3w05d&123456', - ]), 'current_password', 'The current password field is required.'); -}); - -it('should throw an exception if the new password is too short', function () { - $user = createUserModel(); - - expectValidationError(fn () => resolve(UpdateUserPassword::class)->update($user, [ - 'current_password' => 'password', - 'password' => 'Pas3w05d&', - 'password_confirmation' => 'Pas3w05d&', - ]), 'password', 'The password field must be at least 12 characters.'); -}); - -it('should throw an exception if the new password is too weak', function () { - $user = createUserModel(); - - expectValidationError(fn () => resolve(UpdateUserPassword::class)->update($user, [ - 'current_password' => 'password', - 'password' => 'weak', - ]), 'password', 'The password field must be at least 12 characters.'); -}); - -it('should throw an exception if the new password is not confirmed', function () { - $user = createUserModel(); - - expectValidationError(fn () => resolve(UpdateUserPassword::class)->update($user, [ - 'current_password' => 'password', - 'password' => 'Pas3w05d&123456', - 'password_confirmation' => null, - ]), 'password_confirmation', 'The password confirmation field must match password.'); -}); - -it('should throw an exception if the new password confirmation does not match', function () { - $user = createUserModel(); - - expectValidationError(fn () => resolve(UpdateUserPassword::class)->update($user, [ - 'current_password' => 'password', - 'password' => 'Pas3w05d&123456', - 'password_confirmation' => 'password', - ]), 'password_confirmation', 'The password confirmation field must match password.'); -}); diff --git a/tests/Fortify/Actions/UpdateUserProfileInformationTest.php b/tests/Fortify/Actions/UpdateUserProfileInformationTest.php deleted file mode 100644 index 7f8aa247c..000000000 --- a/tests/Fortify/Actions/UpdateUserProfileInformationTest.php +++ /dev/null @@ -1,127 +0,0 @@ -name)->toBe('John Doe'); - expect($user->email)->toBe('john@doe.com'); - - resolve(UpdateUserProfileInformation::class)->update($user, [ - 'name' => 'Jane Doe', - 'email' => 'jane@doe.com', - ]); - - expect($user->name)->toBe('Jane Doe'); - expect($user->email)->toBe('jane@doe.com'); -}); - -it('should update the profile information for a user that requires verification', function () { - $user = createUserModel(UserWithNotifications::class); - - expect($user->name)->toBe('John Doe'); - expect($user->email)->toBe('john@doe.com'); - expect($user->email_verified_at)->not()->toBeNull(); - - resolve(UpdateUserProfileInformation::class)->update($user, [ - 'name' => 'Jane Doe', - 'email' => 'jane@doe.com', - ]); - - expect($user->name)->toBe('Jane Doe'); - expect($user->email)->toBe('jane@doe.com'); - expect($user->email_verified_at)->toBeNull(); -}); - -it('should update with lowercase email', function () { - $user = createUserModel(UserWithoutVerification::class); - - expect($user->name)->toBe('John Doe'); - expect($user->email)->toBe('john@doe.com'); - - resolve(UpdateUserProfileInformation::class)->update($user, [ - 'name' => 'Jane Doe', - 'email' => 'JANE@DOE.COM', - ]); - - expect($user->name)->toBe('Jane Doe'); - expect($user->email)->toBe('jane@doe.com'); -}); - -it('should update with lowercase email for a user that requires verification', function () { - $user = createUserModel(UserWithNotifications::class); - - expect($user->name)->toBe('John Doe'); - expect($user->email)->toBe('john@doe.com'); - expect($user->email_verified_at)->not()->toBeNull(); - - resolve(UpdateUserProfileInformation::class)->update($user, [ - 'name' => 'Jane Doe', - 'email' => 'JANE@DOE.COM', - ]); - - expect($user->name)->toBe('Jane Doe'); - expect($user->email)->toBe('jane@doe.com'); - expect($user->email_verified_at)->toBeNull(); -}); - -it('should throw an exception if the name is missing', function () { - $user = createUserModel(); - - expectValidationError(fn () => resolve(UpdateUserProfileInformation::class)->update($user, [ - 'name' => null, - 'email' => 'jane@doe.com', - ]), 'name', 'The name field is required.'); -}); - -it('should throw an exception if the name is too short', function () { - $user = createUserModel(); - - expectValidationError(fn () => resolve(UpdateUserProfileInformation::class)->update($user, [ - 'name' => str_repeat('a', 2), - 'email' => 'jane@doe.com', - ]), 'name', 'The name field must be at least 3 characters.'); -}); - -it('should throw an exception if the name is too long', function () { - $user = createUserModel(); - - expectValidationError(fn () => resolve(UpdateUserProfileInformation::class)->update($user, [ - 'name' => 'a'.str_repeat('a', 31), - 'email' => 'jane@doe.com', - ]), 'name', 'The name field must not be greater than 30 characters.'); -}); - -it('should throw an exception if the email is missing', function () { - $user = createUserModel(); - - expectValidationError(fn () => resolve(UpdateUserProfileInformation::class)->update($user, [ - 'name' => 'Jane Doe', - 'email' => null, - ]), 'email', 'The email field is required.'); -}); - -it('should throw an exception if the email is too long', function () { - $user = createUserModel(); - - expectValidationError(fn () => resolve(UpdateUserProfileInformation::class)->update($user, [ - 'name' => 'Jane Doe', - 'email' => str_repeat('#', 256).'@doe.com', - ]), 'email', 'The email field must not be greater than 255 characters.'); -}); - -it('should throw an exception if the email is not an email', function () { - $user = createUserModel(); - - expectValidationError(fn () => resolve(UpdateUserProfileInformation::class)->update($user, [ - 'name' => 'Jane Doe', - 'email' => str_repeat('#', 256), - ]), 'email', 'The email field must be a valid email address.'); -}); diff --git a/tests/Fortify/Components/DeleteUserFormTest.php b/tests/Fortify/Components/DeleteUserFormTest.php deleted file mode 100644 index fca07269a..000000000 --- a/tests/Fortify/Components/DeleteUserFormTest.php +++ /dev/null @@ -1,127 +0,0 @@ - [])->name('home'); - - $user = createUserModel(); - - $this->mock(DeleteUser::class) - ->shouldReceive('delete'); - - Livewire::actingAs($user) - ->test(DeleteUserForm::class) - ->assertViewIs('ark-fortify::profile.delete-user-form') - ->call('confirmUserDeletion') - ->assertSee(trans('ui::pages.user-settings.delete_account_description')) - ->set('confirmedPassword', 'password') - ->call('deleteUser') - ->assertRedirect('/'); - - $this->assertNull(Auth::user()); -}); - -it('can interact with the form and leave a feedback', function () { - Mail::fake(); - - $user = createUserModel(); - - $this->mock(DeleteUser::class) - ->shouldReceive('delete'); - - Livewire::actingAs($user) - ->test(DeleteUserForm::class) - ->assertViewIs('ark-fortify::profile.delete-user-form') - ->call('confirmUserDeletion') - ->assertSee(trans('ui::pages.user-settings.delete_account_description')) - ->set('confirmedPassword', 'password') - ->set('feedback', 'my feedback here') - ->call('deleteUser') - ->assertRedirect(URL::temporarySignedRoute('profile.feedback.thank-you', now()->addMinutes(15))); - $this->assertNull(Auth::user()); - - Mail::assertQueued(SendFeedback::class, function ($mail) { - return $mail->hasTo(config('fortify.mail.feedback.address')) && - $mail->message === 'my feedback here'; - }); -}); - -it('cant delete user with an incorrect password', function () { - $user = createUserModel(); - - $this->mock(DeleteUser::class) - ->shouldReceive('delete'); - - Livewire::actingAs($user) - ->test(DeleteUserForm::class) - ->assertViewIs('ark-fortify::profile.delete-user-form') - ->call('confirmUserDeletion') - ->assertSee(trans('ui::pages.user-settings.delete_account_description')) - ->call('deleteUser') - ->set('confirmedPassword', 'invalid-password') - ->call('deleteUser'); - $this->assertNotNull(Auth::user()); -}); - -it('clears the error when updating the value', function () { - $user = createUserModel(); - - $this->mock(DeleteUser::class) - ->shouldReceive('delete'); - - Livewire::actingAs($user) - ->test(DeleteUserForm::class) - ->assertViewIs('ark-fortify::profile.delete-user-form') - ->call('confirmUserDeletion') - ->assertSee(trans('ui::pages.user-settings.delete_account_description')) - ->set('confirmedPassword', 'invalid-password') - ->set('feedback', 'ab') - ->call('deleteUser') - ->assertHasErrors('confirmedPassword') - ->assertHasErrors('feedback') - ->set('confirmedPassword', 'updted-password') - ->set('feedback', 'abcde') - ->assertHasNoErrors(); - - $this->assertNotNull(Auth::user()); -}); - -it('cant delete user without a password', function () { - $user = createUserModel(); - - $this->mock(DeleteUser::class) - ->shouldReceive('delete'); - - Livewire::actingAs($user) - ->test(DeleteUserForm::class) - ->assertViewIs('ark-fortify::profile.delete-user-form') - ->call('confirmUserDeletion') - ->assertSee(trans('ui::pages.user-settings.delete_account_description')) - ->call('deleteUser'); - - $this->assertNotNull(Auth::user()); -}); - -it('displays alert when set', function () { - $user = createUserModel(); - - Livewire::actingAs($user) - ->test(DeleteUserForm::class) - ->set('modalShown', true) - ->assertDontSee('alert-wrapper') - ->set('alert', 'a test alertwith html.') - ->assertSee('alert-wrapper'); -}); diff --git a/tests/Fortify/Components/ExportUserDataTest.php b/tests/Fortify/Components/ExportUserDataTest.php deleted file mode 100644 index 0ddaa779a..000000000 --- a/tests/Fortify/Components/ExportUserDataTest.php +++ /dev/null @@ -1,50 +0,0 @@ -test(ExportUserData::class) - ->call('export') - ->assertDispatched('toastMessage', [ - 'message' => trans('ui::pages.user-settings.data_exported'), - 'type' => 'success', - ]); - - Bus::assertDispatched(CreatePersonalDataExportJob::class); -}); - -it('can only export the user data once every 15 min', function () { - Bus::fake(); - - $component = Livewire::actingAs(createUserModel()) - ->test(ExportUserData::class) - ->call('export') - ->assertDispatched('toastMessage', [ - 'message' => trans('ui::pages.user-settings.data_exported'), - 'type' => 'success', - ]) - ->call('export') - ->assertNotDispatched('toastMessage', [ - 'message' => trans('ui::pages.user-settings.data_exported'), - 'type' => 'success', - ]); - - $this->travel(16)->minutes(); - - $component->call('export') - ->assertDispatched('toastMessage', [ - 'message' => trans('ui::pages.user-settings.data_exported'), - 'type' => 'success', - ]); - - Bus::assertDispatched(CreatePersonalDataExportJob::class); -}); diff --git a/tests/Fortify/Components/FooterEmailSubscriptionFormTest.php b/tests/Fortify/Components/FooterEmailSubscriptionFormTest.php deleted file mode 100644 index 306de0e6e..000000000 --- a/tests/Fortify/Components/FooterEmailSubscriptionFormTest.php +++ /dev/null @@ -1,70 +0,0 @@ -test(FooterEmailSubscriptionForm::class) - ->assertSet('subscribed', false) - ->assertSet('email', null) - ->assertSet('status', null) - ->assertViewIs('ark-fortify::newsletter.footer-subscription-form'); -}); - -it('should handle duplicate entries', function () { - Config::set('newsletter.apiKey', 'test-test'); - Config::set('newsletter.lists.subscribers.id', 'list-id'); - - Newsletter::shouldReceive('isSubscribed') - ->andReturn(true) - ->once(); - - $user = createUserModel(); - - Livewire::actingAs($user) - ->test(FooterEmailSubscriptionForm::class) - ->assertSet('subscribed', false) - ->assertSet('email', null) - ->assertSet('status', null) - ->set('email', 'email@email.com') - ->call('subscribe') - ->assertSet('subscribed', false) - ->assertSet('status', trans('ui::messages.subscription.duplicate')) - ->assertViewIs('ark-fortify::newsletter.footer-subscription-form'); -}); - -it('should handle subscription', function () { - Config::set('newsletter.apiKey', 'test-test'); - Config::set('newsletter.lists.subscribers.id', 'list-id'); - - Newsletter::shouldReceive('isSubscribed') - ->andReturn(false) - ->once(); - - Newsletter::shouldReceive('subscribePending') - ->andReturn(true) - ->once(); - - $user = createUserModel(); - - Livewire::actingAs($user) - ->test(FooterEmailSubscriptionForm::class) - ->assertSet('subscribed', false) - ->assertSet('email', null) - ->assertSet('status', null) - ->set('email', 'email@email.com') - ->call('subscribe') - ->assertSet('subscribed', true) - ->assertSet('status', trans('ui::messages.subscription.pending')) - ->assertViewIs('ark-fortify::newsletter.footer-subscription-form'); -}); diff --git a/tests/Fortify/Components/LogoutOtherBrowserSessionsFormTest.php b/tests/Fortify/Components/LogoutOtherBrowserSessionsFormTest.php deleted file mode 100644 index 585ec8945..000000000 --- a/tests/Fortify/Components/LogoutOtherBrowserSessionsFormTest.php +++ /dev/null @@ -1,112 +0,0 @@ -user = createUserModel(); - Config::set('session.driver', 'database'); -}); - -it('can interact with the form', function () { - Livewire::actingAs($this->user) - ->test(LogoutOtherBrowserSessionsForm::class) - ->assertSee('Logout Other Browser Sessions'); -}); - -it('shows only 3 browser sessions', function () { - $session_1 = createBrowserSessionForUser('1.1.1.1', $this->user, now()->subHours(1)->unix()); - $session_2 = createBrowserSessionForUser('2.2.2.2', $this->user, now()->subHours(2)->unix()); - $session_3 = createBrowserSessionForUser('3.3.3.3', $this->user, now()->subHours(6)->unix()); - $session_4 = createBrowserSessionForUser('4.4.4.4', $this->user, now()->subHours(3)->unix()); - - actingAs($this->user); - - Session::shouldReceive('getId') - ->andReturn($session_1) - ->shouldReceive('token') - ->andReturn('csrf-token'); - - livewire(LogoutOtherBrowserSessionsForm::class) - ->assertSee('1.1.1.1') - ->assertSee('2.2.2.2') - ->assertDontSee('3.3.3.3') - ->assertSee('4.4.4.4'); -}); - -it('removes all other browser sessions for this user', function () { - $session_1 = createBrowserSessionForUser('1.1.1.1', $this->user, now()->subHours(1)->unix()); - $session_2 = createBrowserSessionForUser('2.2.2.2', $this->user, now()->subHours(2)->unix()); - $session_3 = createBrowserSessionForUser('3.3.3.3', $this->user, now()->subHours(6)->unix()); - $session_4 = createBrowserSessionForUser('4.4.4.4', $this->user, now()->subHours(3)->unix()); - - actingAs($this->user); - - Session::shouldReceive('get'); - Session::shouldReceive('forget'); - Session::shouldReceive('getId') - ->andReturn($session_1) - ->shouldReceive('token') - ->andReturn('csrf-token'); - - livewire(LogoutOtherBrowserSessionsForm::class) - ->call('confirmLogout') - ->assertSee('Logout Other Browser Sessions') - ->set('password', 'password') - ->call('logoutOtherBrowserSessions') - ->assertSet('modalShown', false); - - $sessions = DB::table('sessions')->where('user_id', $this->user->id)->get(); - expect(count($sessions))->toBe(1); - expect($sessions[0]->ip_address)->toBe('1.1.1.1'); -}); - -it('should not delete browser sessions of other users', function () { - $other_user = User::create([ - 'name' => 'John Doe 2', - 'username' => 'john.doe.2', - 'email' => 'john2@doe.com', - 'email_verified_at' => Carbon::now(), - 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password - 'remember_token' => Str::random(10), - 'timezone' => 'UTC', - ]); - - $session_1 = createBrowserSessionForUser('1.1.1.1', $this->user, now()->subHours(1)->unix()); - $session_2 = createBrowserSessionForUser('2.2.2.2', $this->user, now()->subHours(2)->unix()); - $session_3 = createBrowserSessionForUser('3.3.3.3', $other_user, now()->subHours(6)->unix()); - - actingAs($this->user); - - Session::shouldReceive('get'); - Session::shouldReceive('forget'); - Session::shouldReceive('getId') - ->andReturn($session_1) - ->shouldReceive('token') - ->andReturn('csrf-token'); - - livewire(LogoutOtherBrowserSessionsForm::class) - ->call('confirmLogout') - ->assertSee('Logout Other Browser Sessions') - ->set('password', 'password') - ->call('logoutOtherBrowserSessions') - ->assertSet('modalShown', false); - - $sessions = DB::table('sessions')->where('user_id', $this->user->id)->get(); - expect(DB::table('sessions')->where('user_id', $other_user->id)->count())->toBe(1); -}); diff --git a/tests/Fortify/Components/RegisterFormTest.php b/tests/Fortify/Components/RegisterFormTest.php deleted file mode 100644 index 156a5bec1..000000000 --- a/tests/Fortify/Components/RegisterFormTest.php +++ /dev/null @@ -1,106 +0,0 @@ -name('terms-of-service'); - Route::get('privacy-policy', function () { - return view(''); - })->name('privacy-policy'); -}); - -it('can interact with the form', function () { - Config::set('fortify.models.invitation', RegisterFormTest::class); - - $invitationUuid = Uuid::uuid(); - - Livewire::withQueryParams(['invitation' => $invitationUuid]) - ->test(RegisterForm::class) - ->set('name', 'John Doe') - ->set('username', 'jdoe') - ->set('email', 'jdoe@example.org') - ->set('email', 'jdoe@example.org') - ->assertViewIs('ark-fortify::auth.register-form') - ->assertViewHas('invitation'); -}); - -it('cannot submit if all required fields are not filled', function () { - Config::set('fortify.models.invitation', RegisterFormTest::class); - - $invitationUuid = Uuid::uuid(); - - $instance = Livewire::withQueryParams(['invitation' => $invitationUuid]) - ->test(RegisterForm::class); - - expect($instance->instance()->canSubmit())->toBeFalse(); - - $instance->set('name', 'John Doe'); - expect($instance->instance()->canSubmit())->toBeFalse(); - - $instance->set('username', 'jdoe'); - expect($instance->instance()->canSubmit())->toBeFalse(); - - $instance->set('email', 'jdoe@example.org'); - expect($instance->instance()->canSubmit())->toBeFalse(); - - $instance->set('password', 'Password420007!'); - expect($instance->instance()->canSubmit())->toBeFalse(); - - $instance->set('password_confirmation', 'Password420007!'); - expect($instance->instance()->canSubmit())->toBeFalse(); - - $instance->set('terms', true); - expect($instance->instance()->canSubmit())->toBeTrue(); -}); - -it('mounts invitation email and prevents updates to the email address if signing up using invitation', function () { - Config::set('fortify.models.invitation', RegisterFormTest::class); - - $invitationUuid = Uuid::uuid(); - - Livewire::withQueryParams(['invitation' => $invitationUuid]) - ->test(RegisterForm::class) - ->assertSet('email', 'jdoe@example.org') - ->set('email', 'john@example.com') - ->assertSet('email', 'jdoe@example.org'); -}); - -it('should correctly validate password & confirm password fields', function () { - Livewire::test(RegisterForm::class) - ->set('password', 'Password420007!') - ->assertHasNoErrors(['password', 'password_confirmation']) - ->set('password_confirmation', 'wrong password') - ->assertHasNoErrors('password') - ->assertHasErrors('password_confirmation') - ->set('password_confirmation', 'Password420007!') - ->assertHasNoErrors(['password', 'password_confirmation']) - ->set('password', 'invalid password') - ->assertHasErrors(['password', 'password_confirmation']); -}); diff --git a/tests/Fortify/Components/ResetPasswordFormTest.php b/tests/Fortify/Components/ResetPasswordFormTest.php deleted file mode 100644 index 5d0d96c55..000000000 --- a/tests/Fortify/Components/ResetPasswordFormTest.php +++ /dev/null @@ -1,38 +0,0 @@ -test(ResetPasswordForm::class) - ->assertSet('email', null) - ->assertSet('password', '') - ->assertSet('password_confirmation', '') - ->assertViewIs('ark-fortify::auth.reset-password-form'); -}); - -it('gets the two factor code and the email', function () { - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - - $user = createUserModel(); - - $user->two_factor_secret = 'secret'; - $user->save(); - - Livewire::actingAs($user) - ->test(ResetPasswordForm::class, ['email' => $user->email]) - ->assertSet('email', $user->email) - ->assertSet('password', '') - ->assertSet('password_confirmation', '') - ->assertSet('twoFactorSecret', 'secret') - ->assertViewIs('ark-fortify::auth.reset-password-form'); -}); diff --git a/tests/Fortify/Components/TwoFactorAuthenticationFormTest.php b/tests/Fortify/Components/TwoFactorAuthenticationFormTest.php deleted file mode 100644 index ec62f5acd..000000000 --- a/tests/Fortify/Components/TwoFactorAuthenticationFormTest.php +++ /dev/null @@ -1,122 +0,0 @@ -mock(Google2FA::class); - $g2FA->shouldReceive('verifyKey') - ->andReturnTrue(); - app()->instance('pragmarx.google2fa', $g2FA); - - $two_factor_secret = 'QHBRXHLWOT3B2T3L'; - Livewire::actingAs($user) - ->test(TwoFactorAuthenticationForm::class) - ->assertSee(trans('ui::pages.user-settings.2fa_not_enabled_title')) - ->set('state.two_factor_secret', $two_factor_secret) - ->assertSet('enabled', false) - ->assertSee($two_factor_secret) - ->set('state.otp', '8437339') - ->call('enableTwoFactorAuthentication') - ->assertHasErrors(['state.otp' => 'digits']) - ->set('state.otp', '843733') - ->call('enableTwoFactorAuthentication') - ->assertSee('Two-Factor Authentication Recovery Codes') - ->assertSee('If you lose your two-factor authentication device') - ->call('regenerateRecoveryCodes') - ->assertSee('Two-Factor Authentication Recovery Codes') - ->call('hideRecoveryCodes') - ->assertSee('You have enabled two-factor authentication') - ->call('showConfirmPassword') - ->assertSee('Input your password to show your emergency two-factor recovery codes.') - ->set('confirmedPassword', 'password') - ->call('showRecoveryCodesAfterPasswordConfirmation') - ->assertSee('If you lose your two-factor authentication device') - ->call('hideRecoveryCodes') - ->call('showDisableConfirmPassword') - ->assertSee('Input your password to disable the two-factor authentication method.') - ->set('confirmedPassword', 'password') - ->call('disableTwoFactorAuthentication') - ->assertSee(trans('ui::pages.user-settings.2fa_not_enabled_title')); -}); - -it('should not show recovery codes if wrong password', function () { - $user = createUserModel(); - - $g2FA = $this->mock(Google2FA::class); - $g2FA->shouldReceive('verifyKey') - ->andReturnTrue(); - app()->instance('pragmarx.google2fa', $g2FA); - - $two_factor_secret = 'QHBRXHLWOT3B2T3L'; - Livewire::actingAs($user) - ->test(TwoFactorAuthenticationForm::class) - ->assertSee(trans('ui::pages.user-settings.2fa_not_enabled_title')) - ->set('state.two_factor_secret', $two_factor_secret) - ->assertSet('enabled', false) - ->assertSee($two_factor_secret) - ->set('state.otp', '843733') - ->call('enableTwoFactorAuthentication') - ->assertSee('Two-Factor Authentication Recovery Codes') - ->call('hideRecoveryCodes') - ->call('showConfirmPassword') - ->assertSee('Input your password to show your emergency two-factor recovery codes.') - ->set('confirmedPassword', 'wrong-password') - ->call('showRecoveryCodesAfterPasswordConfirmation') - ->assertDontSee('If you lose your two-factor authentication device'); -}); - -it('should not disable if wrong password', function () { - $user = createUserModel(); - - $g2FA = $this->mock(Google2FA::class); - $g2FA->shouldReceive('verifyKey') - ->andReturnTrue(); - app()->instance('pragmarx.google2fa', $g2FA); - - $two_factor_secret = 'QHBRXHLWOT3B2T3L'; - Livewire::actingAs($user) - ->test(TwoFactorAuthenticationForm::class) - ->assertSee(trans('ui::pages.user-settings.2fa_not_enabled_title')) - ->set('state.two_factor_secret', $two_factor_secret) - ->assertSet('enabled', false) - ->assertSee($two_factor_secret) - ->set('state.otp', '843733') - ->call('enableTwoFactorAuthentication') - ->assertSee('Two-Factor Authentication Recovery Codes') - ->call('hideRecoveryCodes') - ->call('showDisableConfirmPassword') - ->assertSee('Input your password to disable the two-factor authentication method.') - ->set('confirmedPassword', 'wrong password') - ->call('disableTwoFactorAuthentication') - ->assertDontSee(trans('ui::pages.user-settings.2fa_not_enabled_title')); -}); - -it('shows email after scanning qr-code on mobile device', function (): void { - $user = createUserModel(); - - $instance = Livewire::actingAs($user) - ->test(TwoFactorAuthenticationForm::class) - ->instance(); - - expect($instance->twoFactorQrCodeUrl)->toContain(urlencode($user->email)); -}); - -it('shows username after scanning qr-code on mobile device', function (): void { - Config::set('fortify.username', 'username'); - - $user = createUserModel(); - - $instance = Livewire::actingAs($user) - ->test(TwoFactorAuthenticationForm::class) - ->instance(); - - expect($instance->twoFactorQrCodeUrl)->toContain(urlencode($user->username)); -}); diff --git a/tests/Fortify/Components/UpdatePasswordFormTest.php b/tests/Fortify/Components/UpdatePasswordFormTest.php deleted file mode 100644 index f8bc5f160..000000000 --- a/tests/Fortify/Components/UpdatePasswordFormTest.php +++ /dev/null @@ -1,193 +0,0 @@ -mock(UncompromisedVerifier::class)->shouldReceive('verify')->andReturn(true); -}); - -it('can interact with the form', function () { - $user = createUserModel(); - - Livewire::actingAs($user) - ->test(UpdatePasswordForm::class) - ->assertSet('currentPassword', '') - ->assertSet('password', '') - ->assertSet('password_confirmation', '') - ->assertViewIs('ark-fortify::profile.update-password-form') - ->set('currentPassword', 'password') - ->set('password', 'abcd1234ABCD%') - ->set('password_confirmation', 'abcd1234ABCD%') - ->call('updatePassword') - ->assertDispatched('updated-password') - ->assertDispatched('toastMessage', [ - 'message' => trans('ui::pages.user-settings.password_updated'), - 'type' => 'success', - ]); -}); - -it('clears password rules on update', function () { - $user = createUserModel(); - - Livewire::actingAs($user) - ->test(UpdatePasswordForm::class) - ->set('currentPassword', 'password') - ->set('password', 'abcd1234ABCD%') - ->set('password_confirmation', 'abcd1234ABCD%') - ->assertSet('passwordRules', [ - 'lowercase' => true, - 'uppercase' => true, - 'numbers' => true, - 'symbols' => true, - 'min' => true, - 'leak' => true, - ]) - ->call('updatePassword') - ->assertSet('passwordRules', [ - 'lowercase' => false, - 'uppercase' => false, - 'numbers' => false, - 'symbols' => false, - 'min' => false, - 'leak' => false, - ]); -}); - -it('handles password being null', function () { - $user = createUserModel(); - - Livewire::actingAs($user) - ->test(UpdatePasswordForm::class) - ->assertSet('currentPassword', '') - ->assertSet('password', '') - ->assertSet('password_confirmation', '') - ->assertViewIs('ark-fortify::profile.update-password-form') - ->set('currentPassword', 'password') - ->set('password', null) - ->set('password_confirmation', null) - ->call('updatePassword') - ->assertSet('passwordRules', [ - 'lowercase' => false, - 'uppercase' => false, - 'numbers' => false, - 'symbols' => false, - 'min' => false, - 'leak' => false, - ]); -}); - -it('handles password being empty string', function () { - $user = createUserModel(); - - Livewire::actingAs($user) - ->test(UpdatePasswordForm::class) - ->assertSet('currentPassword', '') - ->assertSet('password', '') - ->assertSet('password_confirmation', '') - ->assertViewIs('ark-fortify::profile.update-password-form') - ->set('currentPassword', 'password') - ->set('password', '') - ->set('password_confirmation', '') - ->call('updatePassword') - ->assertSet('passwordRules', [ - 'lowercase' => false, - 'uppercase' => false, - 'numbers' => false, - 'symbols' => false, - 'min' => false, - 'leak' => false, - ]); -}); - -it('handles password being leaked', function () { - $user = createUserModel(); - - $this->mock(UncompromisedVerifier::class) - ->shouldReceive('verify') - ->with(['value' => 'LeakedPassw0rd!', 'threshold' => 0]) - ->andReturn(false); - - Livewire::actingAs($user) - ->test(UpdatePasswordForm::class) - ->assertSet('currentPassword', '') - ->assertSet('password', '') - ->assertSet('password_confirmation', '') - ->assertViewIs('ark-fortify::profile.update-password-form') - ->set('currentPassword', 'password') - ->set('password', 'LeakedPassw0rd!') - ->set('password_confirmation', 'LeakedPassw0rd!') - ->assertSet('passwordRules', [ - 'lowercase' => true, - 'uppercase' => true, - 'numbers' => true, - 'symbols' => true, - 'min' => true, - 'leak' => false, - ]); -}); - -it('handles password being same', function () { - $user = createUserModel(); - - $user->update(['password' => Hash::make('abcd1234ABCD%')]); - - Livewire::actingAs($user->fresh()) - ->test(UpdatePasswordForm::class) - ->assertSet('currentPassword', '') - ->assertSet('password', '') - ->assertSet('password_confirmation', '') - ->assertViewIs('ark-fortify::profile.update-password-form') - ->set('currentPassword', 'abcd1234ABCD%') - ->set('password', 'abcd1234ABCD%') - ->set('password_confirmation', 'abcd1234ABCD%') - ->assertSet('passwordRules', [ - 'lowercase' => true, - 'uppercase' => true, - 'numbers' => true, - 'symbols' => true, - 'min' => true, - 'leak' => true, - ]) - ->call('updatePassword') - ->assertHasErrors('password', trans('ui::validation.password_current')); -}); - -it('clears password values', function () { - $user = createUserModel(); - - Livewire::actingAs($user) - ->test(UpdatePasswordForm::class) - ->set('currentPassword', 'password') - ->set('password', 'abcd1234ABCD%') - ->set('password_confirmation', 'abcd1234ABCD%') - ->call('updatePassword') - ->assertSet('currentPassword', '') - ->assertSet('password', '') - ->assertSet('password_confirmation', ''); -}); - -it('resets password validation on typing', function () { - $user = createUserModel(); - - Livewire::actingAs($user) - ->test(UpdatePasswordForm::class) - ->assertSet('currentPassword', '') - ->assertSet('password', '') - ->assertSet('password_confirmation', '') - ->assertViewIs('ark-fortify::profile.update-password-form') - ->set('currentPassword', 'password') - ->set('password', 'password') - ->set('password_confirmation', 'password') - ->call('updatePassword') - ->assertHasErrors('password') - ->set('password', 'password12!A%.-') - ->assertHasNoErrors('password'); -}); diff --git a/tests/Fortify/Components/UpdateProfileInformationFormTest.php b/tests/Fortify/Components/UpdateProfileInformationFormTest.php deleted file mode 100644 index 58472eb5a..000000000 --- a/tests/Fortify/Components/UpdateProfileInformationFormTest.php +++ /dev/null @@ -1,18 +0,0 @@ -test(UpdateProfileInformationForm::class) - ->assertSet('state', $user->toArray()) - ->call('updateProfileInformation') - ->assertDispatched('saved') - ->assertDispatched('refresh-navigation-dropdown'); -}); diff --git a/tests/Fortify/Components/UpdateProfilePhotoFormTest.php b/tests/Fortify/Components/UpdateProfilePhotoFormTest.php deleted file mode 100644 index 268249903..000000000 --- a/tests/Fortify/Components/UpdateProfilePhotoFormTest.php +++ /dev/null @@ -1,92 +0,0 @@ -mock(FileAdderFactory::class) - ->shouldReceive('create->withResponsiveImages->usingName->toMediaCollection') - ->once(); - - $photo = UploadedFile::fake()->image('logo.jpeg', 150, 150); - - Livewire::actingAs(MediaUser::fake()) - ->test(UpdateProfilePhotoForm::class) - ->set('imageSingle', $photo); -}); - -it('can upload a photo from path', function () { - Storage::fake('tmp-for-tests'); - - $this - ->mock(FileAdderFactory::class) - ->shouldReceive('create->withResponsiveImages->usingName->toMediaCollection') - ->once(); - - $tempPath = 'vendor/orchestra/testbench-core/laravel/storage/framework/testing/disks/tmp-for-tests/livewire-tmp'; - UploadedFile::fake()->image('logo.jpeg', 150, 150)->move($tempPath, 'logo.jpg'); - - Livewire::actingAs(MediaUser::fake()) - ->test(UpdateProfilePhotoForm::class) - ->set('imageSingle', 'logo.jpg'); -}); - -it('cannot upload a photo with invalid extension', function () { - $photo = UploadedFile::fake()->image('logo.gif', 150, 150)->size(10000); - - Livewire::actingAs(MediaUser::fake()) - ->test(UpdateProfilePhotoForm::class) - ->set('imageSingle', $photo) - ->assertHasErrors('imageSingle'); -}); - -it('cannot upload a photo that is too large', function () { - $photo = UploadedFile::fake()->image('logo.jpg', 150, 150)->size(10000); - - Livewire::actingAs(MediaUser::fake()) - ->test(UpdateProfilePhotoForm::class) - ->set('imageSingle', $photo) - ->assertHasErrors('imageSingle'); -}); - -it('can delete a photo', function () { - $this - ->mock(FileAdderFactory::class) - ->shouldReceive('create->withResponsiveImages->usingName->toMediaCollection') - ->once(); - - $media = Mockery::mock(Media::class); - $media->shouldReceive('delete'); - - $collection = Mockery::mock(MediaCollection::class); - $collection - ->shouldReceive('collectionName') - ->andReturnSelf(); - $collection - ->shouldReceive('first') - ->andReturn($media); - - $this->mock(MediaRepository::class) - ->shouldReceive('getCollection') - ->andReturn($collection); - - $photo = UploadedFile::fake() - ->image('logo.jpeg', 150, 150) - ->size(1); - - Livewire::actingAs(MediaUser::fake()) - ->test(UpdateProfilePhotoForm::class) - ->set('imageSingle', $photo) - ->call('deleteImageSingle') - ->assertHasNoErrors('imageSingle'); -}); diff --git a/tests/Fortify/Components/UpdateTimezoneFormTest.php b/tests/Fortify/Components/UpdateTimezoneFormTest.php deleted file mode 100644 index 7e47e707c..000000000 --- a/tests/Fortify/Components/UpdateTimezoneFormTest.php +++ /dev/null @@ -1,88 +0,0 @@ -actingAs(createUserModel()); - - $this->assertDatabaseHas('users', [ - 'timezone' => 'UTC', - ]); - - Livewire::test(UpdateTimezoneForm::class) - ->assertSet('timezone', 'UTC') - ->assertSee('(UTC+00:00) UTC'); -}); - -it('should not accept an invalid timezone', function () { - $user = createUserModel(); - - $this->actingAs($user); - - $this->assertDatabaseHas('users', [ - 'timezone' => 'UTC', - ]); - - Livewire::test(UpdateTimezoneForm::class) - ->set('timezone', 'Invalid') - ->call('updateTimezone') - ->assertHasErrors('timezone'); - - expect($user->fresh()->timezone)->toBe('UTC'); -}); - -it('should be able to update the timezone', function () { - $this->actingAs(createUserModel()); - - $this->assertDatabaseHas('users', [ - 'timezone' => 'UTC', - ]); - - Livewire::test(UpdateTimezoneForm::class) - ->assertSet('timezone', 'UTC') - ->assertSee('(UTC+00:00) UTC') - ->set('timezone', 'Europe/Amsterdam') - ->call('updateTimezone') - ->assertSet('timezone', 'Europe/Amsterdam') - ->assertSee(') Europe/Amsterdam') - ->assertDispatched('toastMessage', [ - 'message' => trans('ui::pages.user-settings.timezone_updated'), - 'type' => 'success', - ]); - - $this->assertDatabaseHas('users', [ - 'timezone' => 'Europe/Amsterdam', - ]); -}); - -it('should assert that the currentTimezone property is set to UTC by default and is a string', function () { - $user = createUserModel(); - - $this->actingAs($user); - - $realComponent = new UpdateTimezoneForm('1'); - $realComponent->mount(); - - $this->assertSame('UTC', $realComponent->timezone); - $this->assertSame($realComponent->timezone, $user->timezone); -}); - -it('can format a timezone', function () { - $firstTimezone = 'America/Rainy_River'; - $firstFormattedTimezone = str_replace('_', ' ', $firstTimezone); - - $this->assertStringMatchesFormat('%s_%s', $firstTimezone); - $this->assertStringMatchesFormat('%s %s', $firstFormattedTimezone); - $this->assertSame('America/Rainy River', $firstFormattedTimezone); - - $secondTimezone = 'America/North_Dakota/New_Salem'; - $secondFormattedTimezone = str_replace('_', ' ', $secondTimezone); - - $this->assertStringMatchesFormat('%s_%s', $secondTimezone); - $this->assertStringMatchesFormat('%s %s', $secondFormattedTimezone); - $this->assertSame('America/North Dakota/New Salem', $secondFormattedTimezone); -}); diff --git a/tests/Fortify/Components/VerifyEmailTest.php b/tests/Fortify/Components/VerifyEmailTest.php deleted file mode 100644 index 5df1326be..000000000 --- a/tests/Fortify/Components/VerifyEmailTest.php +++ /dev/null @@ -1,34 +0,0 @@ -test(VerifyEmail::class) - ->call('resend') - ->assertDontSeeHtml('wire:loading.attr="disabled"') - ->assertSeeHtml(sprintf('data-tippy-content="%s"', trans('ui::messages.resend_email_verification_limit'))); -}); - -it('can resend a verification email once every 5 minutes', function (): void { - $component = Livewire::actingAs(createUserModel()) - ->test(VerifyEmail::class) - ->call('resend') - ->call('resend') - ->assertDontSeeHtml('wire:loading.attr="disabled"') - ->assertSeeHtml(sprintf('data-tippy-content="%s"', trans('ui::messages.resend_email_verification_limit'))); - - $this->travel(6)->minutes(); - - $component - ->call('$refresh') - ->assertSeeHtml('wire:loading.attr="disabled"') - ->assertDontSeeHtml(sprintf('data-tippy-content="%s"', trans('ui::messages.resend_email_verification_limit'))); -}); diff --git a/tests/Fortify/Http/Controllers/TwoFactorAuthenticatedPasswordResetControllerTest.php b/tests/Fortify/Http/Controllers/TwoFactorAuthenticatedPasswordResetControllerTest.php deleted file mode 100644 index 767ca1de4..000000000 --- a/tests/Fortify/Http/Controllers/TwoFactorAuthenticatedPasswordResetControllerTest.php +++ /dev/null @@ -1,149 +0,0 @@ -mock(TwoFactorResetPasswordRequest::class) - ->shouldReceive('hasChallengedUser') - ->andReturn(true) - ->shouldReceive('hasValidToken') - ->andReturn(true) - ->shouldReceive('challengedUser') - ->andReturn($user); - - $request = app(TwoFactorResetPasswordRequest::class); - - $controller = app(TwoFactorAuthenticatedPasswordResetController::class); - - $token = 'abcd'; - - $response = $controller->create($request, $token); - expect($response)->toBeInstanceOf(View::class); - expect($response->getName())->toBe('ark-fortify::auth.two-factor-challenge'); - expect($response->getData())->toEqual([ - 'token' => $token, - 'resetPassword' => true, - 'email' => $user->email, - ]); -}); - -it('throws an http exception if the token is invalid', function () { - $this->expectException(HttpResponseException::class); - - createUserModel(); - - $this->mock(TwoFactorResetPasswordRequest::class) - ->shouldReceive('hasChallengedUser') - ->andReturn(true) - ->shouldReceive('hasValidToken') - ->andReturn(false); - - $request = app(TwoFactorResetPasswordRequest::class); - - $controller = app(TwoFactorAuthenticatedPasswordResetController::class); - - $token = 'abcd'; - - $controller->create($request, $token); -}); - -it('throws an http exception if is not able to get the user', function () { - $this->expectException(HttpResponseException::class); - - createUserModel(); - - $request = $this->mock(TwoFactorResetPasswordRequest::class) - ->shouldReceive('hasChallengedUser') - ->andReturn(false); - - $request = app(TwoFactorResetPasswordRequest::class); - - $controller = app(TwoFactorAuthenticatedPasswordResetController::class); - - $token = 'abcd'; - - $controller->create($request, $token); -}); - -it('shows the reset form after validating the token', function () { - $user = createUserModel(); - - $user->two_factor_recovery_codes = encrypt('wharever'); - $user->save(); - - $this->mock(TwoFactorResetPasswordRequest::class) - ->shouldReceive('hasChallengedUser') - ->andReturn(true) - ->shouldReceive('hasValidToken') - ->andReturn(true) - ->shouldReceive('challengedUser') - ->andReturn($user) - ->shouldReceive('validRecoveryCode') - ->andReturn(encrypt('the_code')); - - $request = app(TwoFactorResetPasswordRequest::class); - - $controller = app(TwoFactorAuthenticatedPasswordResetController::class); - - $token = 'abcd'; - - $response = $controller->store($request, $token); - expect($response)->toBeInstanceOf(View::class); - expect($response->getName())->toBe('ark-fortify::auth.reset-password'); -}); - -it('throws an http exception if the token is invalid when validating 2fa', function () { - $this->expectException(HttpResponseException::class); - - $user = createUserModel(); - - $this->mock(TwoFactorResetPasswordRequest::class) - ->shouldReceive('challengedUser') - ->andReturn($user) - ->shouldReceive('hasChallengedUser') - ->andReturn(true) - ->shouldReceive('hasValidToken') - ->andReturn(false); - - $request = app(TwoFactorResetPasswordRequest::class); - - $controller = app(TwoFactorAuthenticatedPasswordResetController::class); - - $token = 'abcd'; - - $controller->store($request, $token); -}); - -it('returns a failed two factor login response if the code is invalid', function () { - $user = createUserModel(); - - $this->mock(TwoFactorResetPasswordRequest::class) - ->shouldReceive('challengedUser') - ->andReturn($user) - ->shouldReceive('hasChallengedUser') - ->andReturn(true) - ->shouldReceive('hasValidToken') - ->andReturn(true) - ->shouldReceive('validRecoveryCode') - ->andReturn(false) - ->shouldReceive('hasValidCode') - ->andReturn(false); - - $request = app(TwoFactorResetPasswordRequest::class); - - $controller = app(TwoFactorAuthenticatedPasswordResetController::class); - - $token = 'abcd'; - - $response = $controller->store($request, $token); - expect($response)->toBeInstanceOf(FailedTwoFactorLoginResponse::class); -}); diff --git a/tests/Fortify/Http/Requests/TwoFactorResetPasswordRequestTest.php b/tests/Fortify/Http/Requests/TwoFactorResetPasswordRequestTest.php deleted file mode 100644 index 71e28721b..000000000 --- a/tests/Fortify/Http/Requests/TwoFactorResetPasswordRequestTest.php +++ /dev/null @@ -1,151 +0,0 @@ -mock(PasswordBroker::class) - ->shouldReceive('tokenExists') - ->with($user, $token) - ->andReturn(true); - - $this->partialMock(TwoFactorResetPasswordRequest::class) - ->shouldReceive('route') - ->with('token') - ->andReturn($token) - ->shouldReceive('challengedUser') - ->andReturn($user); - - $request = app(TwoFactorResetPasswordRequest::class); - - expect($request->hasValidToken())->toBeTrue(); - - $this->mock(PasswordBroker::class) - ->shouldReceive('tokenExists') - ->with($user, $token) - ->andReturn(false); - - $request = app(TwoFactorResetPasswordRequest::class); - - expect($request->hasValidToken())->toBeFalse(); -}); - -it('validates the user', function () { - $user = createUserModel(); - - $this->partialMock(TwoFactorResetPasswordRequest::class) - ->shouldReceive('get') - ->with('email') - ->andReturn($user->email) - ->shouldReceive('has') - ->with('email') - ->andReturn(true); - - $this->mock(UserProvider::class) - ->shouldReceive('getModel') - ->andReturn(User::class); - - $this->mock(StatefulGuard::class) - ->shouldReceive('getProvider') - ->andReturn(app(UserProvider::class)); - - $request = app(TwoFactorResetPasswordRequest::class); - - expect($request->hasChallengedUser())->toBeTrue(); -}); - -it('validates not existing user', function () { - createUserModel(); - - $this->partialMock(TwoFactorResetPasswordRequest::class) - ->shouldReceive('get') - ->with('email') - ->andReturn('other@example.com') - ->shouldReceive('has') - ->with('email') - ->andReturn(true); - - $this->mock(UserProvider::class) - ->shouldReceive('getModel') - ->andReturn(User::class); - - $this->mock(StatefulGuard::class) - ->shouldReceive('getProvider') - ->andReturn(app(UserProvider::class)); - - $request = app(TwoFactorResetPasswordRequest::class); - - expect($request->hasChallengedUser())->toBeFalse(); -}); - -it('gets the challenged user', function () { - $user = createUserModel(); - - $this->partialMock(TwoFactorResetPasswordRequest::class) - ->shouldReceive('get') - ->with('email') - ->andReturn($user->email) - ->shouldReceive('has') - ->with('email') - ->andReturn(true); - - $this->mock(UserProvider::class) - ->shouldReceive('getModel') - ->andReturn(User::class); - - $this->mock(StatefulGuard::class) - ->shouldReceive('getProvider') - ->andReturn(app(UserProvider::class)); - - $request = app(TwoFactorResetPasswordRequest::class); - - expect($request->challengedUser()->is($user))->toBeTrue(); - - // A second time, now it comes from the protected property - expect($request->challengedUser()->is($user))->toBeTrue(); -}); - -it('throws an exception if email not found', function () { - $this->expectException(HttpResponseException::class); - - createUserModel(); - - $this->partialMock(TwoFactorResetPasswordRequest::class) - ->shouldReceive('get') - ->with('email') - ->andReturn('other@example.com') - ->shouldReceive('has') - ->with('email') - ->andReturn(true) - ->shouldReceive('only') - ->andReturn([]) - ->shouldReceive('wantsJson') - ->andReturn(false); - - $this->mock(UserProvider::class) - ->shouldReceive('getModel') - ->andReturn(User::class); - - $this->mock(StatefulGuard::class) - ->shouldReceive('getProvider') - ->andReturn(app(UserProvider::class)); - - $this->mock(FailedTwoFactorLoginResponse::class) - ->shouldReceive('toResponse') - ->andReturn(new \Symfony\Component\HttpFoundation\Response()); - - $request = app(TwoFactorResetPasswordRequest::class); - - $request->challengedUser(); -}); diff --git a/tests/Fortify/Http/Responses/FailedPasswordResetLinkRequestResponseTest.php b/tests/Fortify/Http/Responses/FailedPasswordResetLinkRequestResponseTest.php deleted file mode 100644 index d1a6e3562..000000000 --- a/tests/Fortify/Http/Responses/FailedPasswordResetLinkRequestResponseTest.php +++ /dev/null @@ -1,26 +0,0 @@ -toResponse(new Request()); - - expect($response->getStatusCode())->toBe(302); - - expect(app('session.store')->get('errors'))->toBe(null); - - expect(app('session.store')->get('laravel_flash_message'))->toHaveKey('message'); -}); - -it('if the status is for another kind of error return the error response', function () { - $response = new FailedPasswordResetLinkRequestResponse(Password::INVALID_TOKEN); - $response = $response->toResponse(new Request()); - - expect($response->getStatusCode())->toBe(302); - expect(app('session.store')->get('errors')->has('email'))->toBe(true); -}); diff --git a/tests/Fortify/Http/Responses/SuccessfulPasswordResetLinkRequestResponseTest.php b/tests/Fortify/Http/Responses/SuccessfulPasswordResetLinkRequestResponseTest.php deleted file mode 100644 index 524d8fbe8..000000000 --- a/tests/Fortify/Http/Responses/SuccessfulPasswordResetLinkRequestResponseTest.php +++ /dev/null @@ -1,29 +0,0 @@ -toResponse(new Request()); - - expect($response->getStatusCode())->toBe(302); - - expect(app('session.store')->get('laravel_flash_message'))->toHaveKey('message'); -}); - -it('the success json response', function () { - $request = Mockery::mock(Request::class); - $request->shouldReceive('wantsJson') - ->once() - ->andReturnTrue(); - - $response = new SuccessfulPasswordResetLinkRequestResponse(Password::RESET_LINK_SENT); - $response = $response->toResponse($request); - - expect($response->getStatusCode())->toBe(200); - expect($response->getData('message'))->toBe(['message' => 'We have emailed your password reset link.']); -}); diff --git a/tests/Fortify/Mail/SendFeedbackTest.php b/tests/Fortify/Mail/SendFeedbackTest.php deleted file mode 100644 index 3551baf93..000000000 --- a/tests/Fortify/Mail/SendFeedbackTest.php +++ /dev/null @@ -1,26 +0,0 @@ -send(new SendFeedback('feedback')); - - Mail::assertQueued(SendFeedback::class, fn ($mail) => $mail->hasTo(config('fortify.mail.feedback.address'))); -}); - -it('builds the mail with sender', function () { - $mail = new SendFeedback('feedback'); - - expect($mail->build()->from)->toBe([config('fortify.mail.default')]); -}); - -it('builds the mail with subject', function () { - $mail = new SendFeedback('feedback'); - - expect($mail->build()->subject)->toBe(trans('ui::mails.feedback_subject')); -}); diff --git a/tests/Fortify/MediaUser.php b/tests/Fortify/MediaUser.php deleted file mode 100644 index 73caec04a..000000000 --- a/tests/Fortify/MediaUser.php +++ /dev/null @@ -1,29 +0,0 @@ - 'John Doe', - 'username' => 'john.doe', - 'email' => 'john@doe.com', - 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password - 'remember_token' => Str::random(10), - 'timezone' => 'UTC', - ]); - } -} diff --git a/tests/Fortify/Models/Concerns/HasLocalizedTimestampsTest.php b/tests/Fortify/Models/Concerns/HasLocalizedTimestampsTest.php deleted file mode 100644 index c6cc7c415..000000000 --- a/tests/Fortify/Models/Concerns/HasLocalizedTimestampsTest.php +++ /dev/null @@ -1,74 +0,0 @@ -getMockForTrait(HasLocalizedTimestamps::class, [], '', true, true, true, ['getFirstMediaUrl']); - $subject->created_at = Carbon::parse('2021-01-26T19:00:00-0000'); - - $value = $subject->getCreatedAtLocalAttribute(); - - expect($value)->toBeInstanceOf(Carbon::class); - expect($value->format(Carbon::ISO8601))->toBe('2021-01-26T20:00:00+0100'); - expect($value->timezone->getName())->toBe('Africa/Brazzaville'); -}); - -it('can access created at with timezone with authenticated user', function () { - $user = MediaUser::fake(); - $user->timezone = 'America/Argentina/Buenos_Aires'; - $this->actingAs($user); - - $subject = $this->getMockForTrait(HasLocalizedTimestamps::class, [], '', true, true, true, ['getFirstMediaUrl']); - $subject->created_at = Carbon::parse('2021-01-26T19:00:00-0000'); - - $value = $subject->getCreatedAtLocalAttribute(); - - expect($value)->toBeInstanceOf(Carbon::class); - expect($value->format(Carbon::ISO8601))->toBe('2021-01-26T16:00:00-0300'); - expect($value->timezone->getName())->toBe('America/Argentina/Buenos_Aires'); -}); - -it('can access updated at with timezone with guest user', function () { - Config::set('app.timezone', 'Africa/Brazzaville'); - $subject = $this->getMockForTrait(HasLocalizedTimestamps::class, [], '', true, true, true, ['getFirstMediaUrl']); - $subject->updated_at = Carbon::parse('2021-01-26T19:00:00-0000'); - - $value = $subject->getUpdatedAtLocalAttribute(); - - expect($value)->toBeInstanceOf(Carbon::class); - expect($value->format(Carbon::ISO8601))->toBe('2021-01-26T20:00:00+0100'); - expect($value->timezone->getName())->toBe('Africa/Brazzaville'); -}); - -it('can access updated at with timezone with authenticated user', function () { - $user = MediaUser::fake(); - $user->timezone = 'America/Argentina/Buenos_Aires'; - $this->actingAs($user); - - $subject = $this->getMockForTrait(HasLocalizedTimestamps::class, [], '', true, true, true, ['getFirstMediaUrl']); - $subject->updated_at = Carbon::parse('2021-01-26T19:00:00-0000'); - - $value = $subject->getUpdatedAtLocalAttribute(); - - expect($value)->toBeInstanceOf(Carbon::class); - expect($value->format(Carbon::ISO8601))->toBe('2021-01-26T16:00:00-0300'); - expect($value->timezone->getName())->toBe('America/Argentina/Buenos_Aires'); -}); diff --git a/tests/Fortify/Models/Concerns/HasPhotoTest.php b/tests/Fortify/Models/Concerns/HasPhotoTest.php deleted file mode 100644 index a6df84bd6..000000000 --- a/tests/Fortify/Models/Concerns/HasPhotoTest.php +++ /dev/null @@ -1,50 +0,0 @@ -getMockForTrait(HasPhoto::class, [], '', true, true, true, ['getFirstMedia']); - $subject->expects($this->any()) - ->method('getFirstMedia') - ->will($this->returnValue($media)); - - expect($subject->getPhoto())->toBe($media); -}); - -it('can access the photo url', function () { - $subject = $this->getMockForTrait(HasPhoto::class, [], '', true, true, true, ['getFirstMediaUrl']); - $subject->expects($this->any()) - ->method('getFirstMediaUrl') - ->will($this->returnValue('a url')); - - expect($subject->getPhotoAttribute())->toBe('a url'); -}); - -it('can register media collections', function () { - $collection = Mockery::mock(MediaCollection::class); - $collection->shouldReceive('singleFile'); - - $subject = $this->getMockForTrait(HasPhoto::class, [], '', true, true, true, ['addMediaCollection']); - $subject->expects($this->any()) - ->method('addMediaCollection') - ->will($this->returnValue($collection)); - - $subject->registerMediaCollections(); -}); diff --git a/tests/Fortify/ModelsTest.php b/tests/Fortify/ModelsTest.php deleted file mode 100644 index e00b2d0bd..000000000 --- a/tests/Fortify/ModelsTest.php +++ /dev/null @@ -1,18 +0,0 @@ -toBe('users'); -}); - -it('returns the invitations model from config', function () { - Config::set('fortify.models.invitation', 'invites'); - expect(Models::invitation())->toBe('invites'); -}); diff --git a/tests/Fortify/Responses/FailedTwoFactorLoginResponseTest.php b/tests/Fortify/Responses/FailedTwoFactorLoginResponseTest.php deleted file mode 100644 index 8497f08e0..000000000 --- a/tests/Fortify/Responses/FailedTwoFactorLoginResponseTest.php +++ /dev/null @@ -1,51 +0,0 @@ -shouldReceive('only') - ->once() - ->andReturn(['key' => 'value']); - $request->shouldReceive('wantsJson') - ->once() - ->andReturnTrue(); - - (new FailedTwoFactorLoginResponse())->toResponse($request); -})->throws(ValidationException::class); - -it('can return redirect back', function () { - $session = Mockery::mock(\Illuminate\Session\Store::class); - $session->shouldReceive('get') - ->once() - ->with('login.idFailure') - ->andReturn('whatever'); - $session->shouldReceive('put') - ->once() - ->with([ - 'login.id' => 'whatever', - ]); - - $request = Mockery::mock(\Illuminate\Http\Request::class); - $request->shouldReceive('only') - ->once() - ->andReturn(['key' => 'value']); - $request->shouldReceive('wantsJson') - ->once() - ->andReturnFalse(); - $request->shouldReceive('session') - ->twice() - ->andReturn($session); - - $response = (new FailedTwoFactorLoginResponse())->toResponse($request); - - expect($response)->toBeInstanceOf(RedirectResponse::class); - expect($response->status())->toBe(302); -}); diff --git a/tests/Fortify/Responses/RegisterResponseTest.php b/tests/Fortify/Responses/RegisterResponseTest.php deleted file mode 100644 index dadf60c77..000000000 --- a/tests/Fortify/Responses/RegisterResponseTest.php +++ /dev/null @@ -1,117 +0,0 @@ -shouldReceive('wantsJson') - ->once() - ->andReturnTrue(); - - $response = (new RegisterResponse())->toResponse($request); - - expect($response)->toBeInstanceOf(JsonResponse::class); - expect($response->getData())->toBe(''); -}); - -it('redirects to the accept invite route', function () { - Config::set('fortify.models.invitation', \Tests\Fortify\stubs\TestUser::class); - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - Config::set('fortify.accept_invitation_route', 'invitations.accept'); - - $user = User::factory()->create(); - - // Initialize the invitation - $invitation = Models::invitation()::findByUuid('uuid-uuid-uuid-uuid'); - $invitation->update(['user_id' => $user->id]); - - $this->mock(\Illuminate\Contracts\Routing\UrlGenerator::class, function (MockInterface $mock) use ($invitation) { - $mock->shouldReceive('route') - ->with('invitations.accept', $invitation) - ->andReturn('http://localhost/accept-invite'); - }); - - $request = Mockery::mock(\Illuminate\Http\Request::class); - - $request - ->shouldReceive('wantsJson') - ->once() - ->andReturnFalse(); - - $request - ->shouldReceive('get') - ->with('invitation') - ->once() - ->andReturn('uuid-uuid-uuid-uuid'); - - $request - ->shouldReceive('user') - ->once() - ->andReturn($user); - - $response = (new RegisterResponse())->toResponse($request); - - expect($response)->toBeInstanceOf(RedirectResponse::class); - expect($response->status())->toBe(302); - expect($response->content())->toContain('http://localhost/accept-invite'); -}); - -it('redirects to the root url if no route for accept an invitation is set and the user is not an instance of MustVerifyMail', function () { - Config::set('fortify.models.invitation', \Tests\Fortify\stubs\TestUser::class); - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - Config::set('fortify.accept_invitation_route', null); - - $user = User::factory()->create(); - - $request = Mockery::mock(\Illuminate\Http\Request::class); - - $request - ->shouldReceive('wantsJson') - ->once() - ->andReturnFalse() - ->shouldReceive('user') - ->once() - ->andReturnTrue(); - - $response = (new RegisterResponse())->toResponse($request); - - expect($response)->toBeInstanceOf(RedirectResponse::class); - expect($response->status())->toBe(302); - expect($response->content())->toContain('/'); -}); - -it('can redirect on the verification.notice page if no route for accept an invitation is set and the user is an instance of MustVerifyMail', function () { - Config::set('fortify.models.invitation', \Tests\Fortify\stubs\TestUser::class); - Config::set('fortify.models.user', \ARKEcosystem\Foundation\Fortify\Models\User::class); - Config::set('fortify.accept_invitation_route', null); - - $user = User::factory()->create(); - - $request = Mockery::mock(\Illuminate\Http\Request::class); - - $request - ->shouldReceive('wantsJson') - ->once() - ->andReturnFalse() - ->shouldReceive('user') - ->once() - ->andReturn($user); - - $response = (new RegisterResponse())->toResponse($request); - - expect($response)->toBeInstanceOf(RedirectResponse::class); - expect($response->status())->toBe(302); - expect($response->content())->toContain(route('verification.notice')); -}); diff --git a/tests/Fortify/Responses/TwoFactorLoginResponseTest.php b/tests/Fortify/Responses/TwoFactorLoginResponseTest.php deleted file mode 100644 index 5d64510b7..000000000 --- a/tests/Fortify/Responses/TwoFactorLoginResponseTest.php +++ /dev/null @@ -1,70 +0,0 @@ -shouldReceive('wantsJson') - ->once() - ->andReturnTrue(); - - $response = (new TwoFactorLoginResponse())->toResponse($request); - - expect($response)->toBeInstanceOf(JsonResponse::class); - expect($response->getData())->toBe(''); -}); - -it('can return redirect to intended url', function () { - $session = Mockery::mock(\Illuminate\Session\Store::class); - $session->shouldReceive('has') - ->once() - ->with('url.intended') - ->andReturnTrue(); - $session->shouldReceive('pull') - ->once() - ->with('url.intended') - ->andReturn('somewhere'); - - $request = Mockery::mock(\Illuminate\Http\Request::class); - $request->shouldReceive('wantsJson') - ->once() - ->andReturnFalse(); - $request->shouldReceive('session') - ->twice() - ->andReturn($session); - - $response = (new TwoFactorLoginResponse())->toResponse($request); - - expect($response)->toBeInstanceOf(RedirectResponse::class); - expect($response->status())->toBe(302); - expect($response->content())->toContain('somewhere'); -}); - -it('can return redirect home', function () { - $session = Mockery::mock(\Illuminate\Session\Store::class); - $session->shouldReceive('has') - ->once() - ->with('url.intended') - ->andReturnFalse(); - - $request = Mockery::mock(\Illuminate\Http\Request::class); - $request->shouldReceive('wantsJson') - ->once() - ->andReturnFalse(); - $request->shouldReceive('session') - ->once() - ->andReturn($session); - - $response = (new TwoFactorLoginResponse())->toResponse($request); - - expect($response)->toBeInstanceOf(RedirectResponse::class); - expect($response->status())->toBe(302); - expect($response->content())->toContain(config('fortify.home')); -}); diff --git a/tests/Fortify/Rules/Concerns/ReservedUsernameTest.php b/tests/Fortify/Rules/Concerns/ReservedUsernameTest.php deleted file mode 100644 index 31e219d8e..000000000 --- a/tests/Fortify/Rules/Concerns/ReservedUsernameTest.php +++ /dev/null @@ -1,37 +0,0 @@ -subject = new ReservedUsername(); -}); - -it('doesnt allow adding username that is blacklisted', function ($username) { - expect($this->subject->passes('username', $username))->toBeFalse(); - - expect($this->subject->message())->toBe(trans('ui::validation.messages.username.blacklisted')); -})->with([ - 'admin', - 'root', - 'www', - 'president', - 'server', - 'staff', - 'Admin', - 'RoOt', - 'Www', - 'PresIDent', - 'ServEr', - 'StAfF', -]); - -it('allows adding username that isn\'t blacklisted', function ($username) { - expect($this->subject->passes('username', $username))->toBeTrue(); -})->with([ - 'johndoe', - 'john.doe', - 'aboutme', - 'about.you', -]); diff --git a/tests/Fortify/Rules/DisplayNameCharactersTest.php b/tests/Fortify/Rules/DisplayNameCharactersTest.php deleted file mode 100644 index 552c4eb50..000000000 --- a/tests/Fortify/Rules/DisplayNameCharactersTest.php +++ /dev/null @@ -1,102 +0,0 @@ -subject = new DisplayNameCharacters(); -}); - -it('accepts name with regular characters', function ($name) { - $this->assertTrue($this->subject->passes('name', $name)); -})->with([ - 'Elon Tusk', - 'Rick Astley', - 'Los Pollos Hermanos', - 'Alix', - 'H4nn3 Andersen', - 'Hans', - 'Michel The 3rd', - '3llo', -]); - -it('accepts name with unicode characters', function ($name) { - $this->assertTrue($this->subject->passes('name', $name)); -})->with([ - 'André Svenson', - 'John Elkjærd', - 'X Æ A-12', - 'Ñoño', - 'François Hollande', - 'Jean-François d\'Abiguäel', - 'Jean-François d’Abiguäel', - 'Père Noël', - 'Alfonso & sons', - 'Coca.Cola', - 'Procter, Cremin and Crist', -]); - -it('accepts name with single quote', function () { - $this->assertTrue($this->subject->passes('name', 'Marco d\'Almeida')); -}); - -it('doesnt accept other special characters', function ($name) { - $this->assertFalse($this->subject->passes('name', $name)); -})->with([ - 'Martin Henriksen!', - '@alfonsobries', - 'php=cool', - '🤓', // EMOJI - '¯', // MACRON - '­', // SOFT HYPHEN - '–', // EN DASH - '‑', // NON-BREAKING HYPHEN - '—', // EM DASH - '_', // UNDERSCORE -]); - -it('doesnt accept repetitive characters', function ($name) { - expect($this->subject->passes('name', $name))->toBeFalse(); - - expect($this->subject->message())->toBe(trans('ui::validation.messages.some_special_characters')); -})->with([ - 'Marco d\'\'Almeida', - 'Marco d’’Almeida', - 'Alfonso && sons', - 'Jean--François', - 'Coca..Cola', - 'Procter,, Cremin and Crist', -]); - -it('has a message', function () { - $this->assertEquals(trans('ui::validation.messages.some_special_characters'), $this->subject->message()); -}); - -it('will reject if the value contains any blacklisted name', function ($name) { - expect($this->subject->passes('name', $name))->toBeFalse(); - - expect($this->subject->message())->toBe(trans('ui::validation.messages.username.blacklisted')); -})->with([ - 'admin', - 'root', - 'www', - 'president', - 'server', - 'staff', - 'Admin', - 'RoOt', - 'Www', - 'PresIDent', - 'ServEr', - 'StAfF', -]); - -it('will not reject if the value does not contain blacklisted name', function ($name) { - expect($this->subject->passes('name', $name))->toBeTrue(); -})->with([ - 'johndoe', - 'john.doe', - 'aboutme', - 'about.you', -]); diff --git a/tests/Fortify/Rules/OneLetterTest.php b/tests/Fortify/Rules/OneLetterTest.php deleted file mode 100644 index 6cca4aa90..000000000 --- a/tests/Fortify/Rules/OneLetterTest.php +++ /dev/null @@ -1,30 +0,0 @@ -assertFalse($rule->passes('name', $name)); -})->with([ - '134567', - '....', - '----', - '#@$∞', -]); - -it('accepts a name that include at least one letter', function ($name) { - $rule = new OneLetter(); - $this->assertTrue($rule->passes('name', $name)); -})->with([ - '134a567', - 'b....', - '--c--', - '#@$e∞', -]); - -it('has a message', function () { - $rule = new OneLetter(); - $this->assertEquals(trans('ui::validation.messages.include_letters'), $rule->message()); -}); diff --git a/tests/Fortify/Rules/OneTimePasswordTest.php b/tests/Fortify/Rules/OneTimePasswordTest.php deleted file mode 100644 index a0e4acf0d..000000000 --- a/tests/Fortify/Rules/OneTimePasswordTest.php +++ /dev/null @@ -1,17 +0,0 @@ -passes('password', 'no-secret'))->toBeFalse(); -}); - -it('can provider feedback on what was wrong', function () { - $rule = (new OneTimePassword('secret')); - - expect($rule->message())->toBe('We were not able to enable two-factor authentication with this one-time password.'); -}); diff --git a/tests/Fortify/Rules/StartsWithLetterOrNumberTest.php b/tests/Fortify/Rules/StartsWithLetterOrNumberTest.php deleted file mode 100644 index eb84f6ba7..000000000 --- a/tests/Fortify/Rules/StartsWithLetterOrNumberTest.php +++ /dev/null @@ -1,30 +0,0 @@ -assertTrue($rule->passes('name', $name)); -})->with([ - 'a.alfonso', - 'b-hello', - '3&hello', - '1\'Something', -]); - -it('doesnt accept a name that doesnt start with letter or number', function ($name) { - $rule = new StartsWithLetterOrNumber(); - $this->assertFalse($rule->passes('name', $name)); -})->with([ - '.alfonso', - '-hello', - '&hello', - '\'Something', -]); - -it('has a message', function () { - $rule = new StartsWithLetterOrNumber(); - $this->assertEquals(trans('ui::validation.messages.start_with_letter_or_number'), $rule->message()); -}); diff --git a/tests/Fortify/Rules/UsernameTest.php b/tests/Fortify/Rules/UsernameTest.php deleted file mode 100644 index 4dbdf6890..000000000 --- a/tests/Fortify/Rules/UsernameTest.php +++ /dev/null @@ -1,134 +0,0 @@ -subject = new Username(); -}); - -it('handle null values', function () { - expect($this->subject->passes('username', null))->toBeFalse(); -}); - -it('will reject if the value starts with a special character', function () { - expect($this->subject->passes('username', '_foo'))->toBeFalse(); - expect($this->subject->passes('username', '.foo'))->toBeFalse(); - - expect($this->subject->message())->toBe(trans('ui::validation.messages.username.special_character_start')); -}); - -it('will reject if the value ends with a special character', function () { - expect($this->subject->passes('username', 'foo_'))->toBeFalse(); - expect($this->subject->passes('username', 'foo.'))->toBeFalse(); - - expect($this->subject->message())->toBe(trans('ui::validation.messages.username.special_character_end')); -}); - -it('will reject if the value contains consecutive special chars', function () { - expect($this->subject->passes('username', 'foo__bar'))->toBeFalse(); - expect($this->subject->passes('username', 'foo..bar'))->toBeFalse(); - expect($this->subject->passes('username', 'foo_bar__baz'))->toBeFalse(); - expect($this->subject->passes('username', 'foo.bar..baz'))->toBeFalse(); - expect($this->subject->passes('username', 'consecutive._special_.chars'))->toBeFalse(); - - expect($this->subject->message())->toBe(trans('ui::validation.messages.username.consecutive_special_characters')); -}); - -it('will reject if the value contains any forbidden special chars', function () { - expect($this->subject->passes('username', 'foo!bar'))->toBeFalse(); - expect($this->subject->passes('username', 'foo=bar'))->toBeFalse(); - expect($this->subject->passes('username', 'foo?bar'))->toBeFalse(); - expect($this->subject->passes('username', 'foo&baz'))->toBeFalse(); - expect($this->subject->passes('username', 'foo,baz'))->toBeFalse(); - expect($this->subject->passes('username', 'foo;baz'))->toBeFalse(); - - expect($this->subject->passes('username', 'foo¡baz'))->toBeFalse(); // inverted exclamation mark - expect($this->subject->passes('username', 'foo¿baz'))->toBeFalse(); // inverted question mark - expect($this->subject->passes('username', 'foo⸘baz'))->toBeFalse(); // inverted interrobang - expect($this->subject->passes('username', 'foo‽baz'))->toBeFalse(); // interrobang - expect($this->subject->passes('username', 'foo“baz'))->toBeFalse(); // letf double quotation mark - expect($this->subject->passes('username', 'foo–baz'))->toBeFalse(); // en dash - expect($this->subject->passes('username', 'foo—baz'))->toBeFalse(); // em dash - expect($this->subject->passes('username', 'foo‑baz'))->toBeFalse(); // non-breaking hyphen - expect($this->subject->passes('username', 'f😱😱baz'))->toBeFalse(); // emoji - expect($this->subject->passes('username', 'f(oo)baz'))->toBeFalse(); // parentheses - expect($this->subject->passes('username', 'f[oo]baz'))->toBeFalse(); - expect($this->subject->passes('username', 'f{oo}baz'))->toBeFalse(); - expect($this->subject->passes('username', 'fbaz'))->toBeFalse(); - - expect($this->subject->message())->toBe(trans('ui::validation.messages.username.forbidden_special_characters')); -}); - -it('will reject if the value is too short', function () { - expect($this->subject->passes('username', 'a'))->toBeFalse(); - - expect($this->subject->message()) - ->toBe(trans('ui::validation.messages.username.min_length', [ - 'length' => Constants::MIN_USERNAME_CHARACTERS, - ])); -}); - -it('will reject if the value is too long', function () { - expect($this->subject->passes('username', str_repeat('a', 31)))->toBeFalse(); - - expect($this->subject->message()) - ->toBe(trans('ui::validation.messages.username.max_length', [ - 'length' => Constants::MAX_USERNAME_CHARACTERS, - ])); -}); - -it('would not reject if value is using allowed characters', function () { - expect($this->subject->passes('username', 'foo_bar'))->toBeTrue(); - expect($this->subject->passes('username', 'foo.bar'))->toBeTrue(); - expect($this->subject->passes('username', 'foo_bar.baz'))->toBeTrue(); - expect($this->subject->passes('username', 'foo.bar_baz'))->toBeTrue(); - expect($this->subject->passes('username', 'foo_123'))->toBeTrue(); - expect($this->subject->passes('username', 'foo.123'))->toBeTrue(); - expect($this->subject->passes('username', 'foo_123.baz'))->toBeTrue(); - expect($this->subject->passes('username', 'foo.123_baz'))->toBeTrue(); -}); - -it('will reject if the value contains any uppercase character', function () { - expect($this->subject->passes('username', 'Foo'))->toBeFalse(); - expect($this->subject->passes('username', 'fOo'))->toBeFalse(); - expect($this->subject->passes('username', 'foO'))->toBeFalse(); - expect($this->subject->passes('username', 'Foo_bar'))->toBeFalse(); - expect($this->subject->passes('username', 'foo_Bar'))->toBeFalse(); - expect($this->subject->passes('username', 'Foo_Bar'))->toBeFalse(); - expect($this->subject->passes('username', 'Foo.bar'))->toBeFalse(); - expect($this->subject->passes('username', 'foo.Bar'))->toBeFalse(); - expect($this->subject->passes('username', 'Foo.Bar'))->toBeFalse(); - - expect($this->subject->message())->toBe(trans('ui::validation.messages.username.lowercase_only')); -}); - -it('will not reject if the value contains only lowercase character', function () { - expect($this->subject->passes('username', 'foo'))->tobeTrue(); - expect($this->subject->passes('username', 'foo_bar'))->tobeTrue(); - expect($this->subject->passes('username', 'foo.bar'))->tobeTrue(); -}); - -it('will reject if the value contains any blacklisted name', function ($username) { - expect($this->subject->passes('username', $username))->toBeFalse(); - - expect($this->subject->message())->toBe(trans('ui::validation.messages.username.blacklisted')); -})->with([ - 'admin', - 'root', - 'www', - 'president', - 'server', - 'staff', -]); - -it('will not reject if the value not contains blacklisted name', function ($username) { - expect($this->subject->passes('username', $username))->toBeTrue(); -})->with([ - 'johndoe', - 'john.doe', - 'aboutme', - 'about.you', -]); diff --git a/tests/Fortify/UserWithNotifications.php b/tests/Fortify/UserWithNotifications.php deleted file mode 100644 index 59efc8168..000000000 --- a/tests/Fortify/UserWithNotifications.php +++ /dev/null @@ -1,28 +0,0 @@ - 'John Doe', - 'username' => 'john.doe', - 'email' => 'john@doe.com', - 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password - 'remember_token' => Str::random(10), - 'timezone' => 'UTC', - ]); - } -} diff --git a/tests/Fortify/UserWithoutVerification.php b/tests/Fortify/UserWithoutVerification.php deleted file mode 100644 index 595fc8a49..000000000 --- a/tests/Fortify/UserWithoutVerification.php +++ /dev/null @@ -1,18 +0,0 @@ - 'datetime', - ]; -} diff --git a/tests/Fortify/stubs/TestUser.php b/tests/Fortify/stubs/TestUser.php deleted file mode 100644 index 4bae160d3..000000000 --- a/tests/Fortify/stubs/TestUser.php +++ /dev/null @@ -1,52 +0,0 @@ -user_id = Arr::get($attributes, 'user_id', $this->user_id); - $this->uuid = Arr::get($attributes, 'uuid', $this->uuid); - } - - public function user() - { - if (! $this->user_id) { - return; - } - - return Models::user()::find($this->user_id); - } -} diff --git a/tests/Helpers.php b/tests/Helpers.php index a3f3b7691..5a9c091a9 100644 --- a/tests/Helpers.php +++ b/tests/Helpers.php @@ -4,7 +4,7 @@ namespace Tests; -use ARKEcosystem\Foundation\Fortify\Models\User; +use ARKEcosystem\Foundation\Blog\Models\User; use Carbon\Carbon; use Closure; use Illuminate\Support\Facades\DB; diff --git a/tests/Pest.php b/tests/Pest.php index 1060d6767..0791a3eef 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -4,6 +4,7 @@ use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\Blog\TestCase as BlogTestCase; +use Tests\Rules\TestCase as RulesTestCase; use Tests\TestCase; uses(TestCase::class, RefreshDatabase::class)->in( @@ -11,10 +12,9 @@ 'CommonMark', 'DataBags', 'Documentation', - 'Fortify', 'NumberFormatter', - 'Rules', 'Support', 'UserInterface', ); -uses(BlogTestCase::class, RefreshDatabase::class)->in('Blog'); +uses(BlogTestCase::class)->in('Blog'); +uses(RulesTestCase::class)->in('Rules'); diff --git a/tests/Rules/TestCase.php b/tests/Rules/TestCase.php new file mode 100644 index 000000000..0c42f6dd8 --- /dev/null +++ b/tests/Rules/TestCase.php @@ -0,0 +1,56 @@ +withoutVite(); + + $this->loadMigrationsFrom(dirname(__DIR__).'/database/migrations'); + $this->loadMigrationsFrom(dirname(__DIR__).'/Blog/database/migrations'); + } + + protected function getPackageProviders($app) + { + return [ + // Third-Party + FortifyServiceProvider::class, + MarkdownServiceProvider::class, + LivewireServiceProvider::class, + HoneypotServiceProvider::class, + // First-Party + HermesServiceProvider::class, + NewsletterServiceProvider::class, + RulesServiceProvider::class, + UserInterfaceServiceProvider::class, + ]; + } + + protected function afterRefreshingDatabase() + { + $this->loadMigrationsFrom(dirname(__DIR__).'/database/migrations'); + $this->loadMigrationsFrom(dirname(__DIR__).'/Blog/database/migrations'); + } +} diff --git a/tests/Rules/UniqueCaseInsensitiveTest.php b/tests/Rules/UniqueCaseInsensitiveTest.php index a4c14821c..bf591460e 100644 --- a/tests/Rules/UniqueCaseInsensitiveTest.php +++ b/tests/Rules/UniqueCaseInsensitiveTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use ARKEcosystem\Foundation\Fortify\Models\User; +use ARKEcosystem\Foundation\Blog\Models\User; use ARKEcosystem\Foundation\Rules\UniqueCaseInsensitive; beforeEach(function (): void { @@ -19,13 +19,14 @@ $user = User::factory()->create(['username' => 'johndoe']); $user->delete(); - expect($this->subject->withTrashed()->passes(null, 'johndoe'))->toBeTrue(); + expect($this->subject->withTrashed()->passes(null, 'johndoe'))->toBeFalse(); }); it('should exclude trashed data by default', function () { $user = User::factory()->create(['username' => 'johndoe']); + $user->delete(); - expect($this->subject->withTrashed()->passes(null, 'johndoe'))->toBeFalse(); + expect($this->subject->passes(null, 'johndoe'))->toBeTrue(); }); it('should exclude specified data', function () { diff --git a/tests/TestCase.php b/tests/TestCase.php index 404df2789..b77f112e4 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -4,8 +4,6 @@ namespace Tests; -use ARKEcosystem\Foundation\Providers\CommonMarkServiceProvider; -use ARKEcosystem\Foundation\Providers\FortifyServiceProvider; use ARKEcosystem\Foundation\Providers\HermesServiceProvider; use ARKEcosystem\Foundation\Providers\MarkdownServiceProvider; use ARKEcosystem\Foundation\Providers\RulesServiceProvider; @@ -13,7 +11,7 @@ use Illuminate\Foundation\Testing\Concerns\InteractsWithViews; use Illuminate\Support\Facades\View; use Illuminate\Testing\TestView; -use Laravel\Fortify\FortifyServiceProvider as LaravelFortifyServiceProvider; +use Laravel\Fortify\FortifyServiceProvider; use Livewire\LivewireServiceProvider; use Orchestra\Testbench\TestCase as Orchestra; use Spatie\Honeypot\HoneypotServiceProvider; @@ -67,12 +65,11 @@ protected function getPackageProviders($app) { return [ // Third-Party - LaravelFortifyServiceProvider::class, + FortifyServiceProvider::class, MarkdownServiceProvider::class, LivewireServiceProvider::class, HoneypotServiceProvider::class, // First-Party - FortifyServiceProvider::class, HermesServiceProvider::class, NewsletterServiceProvider::class, RulesServiceProvider::class, diff --git a/usage/fortify.md b/usage/fortify.md deleted file mode 100644 index 17c926679..000000000 --- a/usage/fortify.md +++ /dev/null @@ -1,189 +0,0 @@ -# Laravel Fortify - -> Authentication Scaffolding for Laravel. Powered by Laravel Fortify. - -## Installation - -1. Publish all the assets / views with `php artisan vendor:publish --provider="ARKEcosystem\Foundation\Providers\FortifyServiceProvider" --tag=config --tag=images`. - -2. Required Image - -Projects require an image to be provided: `resources/images/auth/verify-email.svg` - -This is omitted from fortify to prevent it being overwritten, but allows for it to be customised per project. - -In the future, a config file may be a better route if there are multiple instances of images being required. - -4. Disable auto-discovery for all fortify packages. This step is required so that we can control the loading order of `laravel/fortify` and `arkecosystem/foundation`. - -```json -"extra": { - "laravel": { - "dont-discover": ["laravel/fortify"] - } -}, -``` - -5. Enable or disable the login/register with username or email by using the `username_alt` setting in the `config/fortify.php` file - -```php - 'username', - // Or set that setting to `null` so the user can only login/register with email: - // 'username_alt' => null, - // ... -]; -``` - -**Note:** If you use the `username_alt` setting, you need to ensure that your users table has that column. - -**Note:** Currently fortify is intended to be used with `'username' => 'email'` in your config, as it expect the `email` property to be set when creating a new user. - -6. Register databags in your `AppServiceProvider` that are used by the auth pages - -```php -use Konceiver\DataBags\DataBag; - -... - -public function boot() -{ - ... - - $this->registerDataBags(); -} - -private function registerDataBags(): void -{ - DataBag::register('fortify-content', [ - 'register' => [ - 'pageTitle' => '', - 'title' => '', - 'description' => '', - ], - 'login' => [ - 'pageTitle' => '', - 'title' => '', - 'description' => '', - // Optional - // 'signupLink' => '', - ], - 'password' => [ - 'reset' => [ - 'pageTitle' => '', - ], - 'request' => [ - 'pageTitle' => '', - ], - ], - 'verification' => [ - 'notice' => [ - 'pageTitle' => '', - ], - 'verify' => [ - 'pageTitle' => '', - ], - 'send' => [ - 'pageTitle' => '', - ], - ], - 'two-factor' => [ - 'login' => [ - 'pageTitle' => '', - ], - ], - ]); -} -``` - -### Two Factor Authentication - -> Under the hood we use [**Pragmarx Google2fa-laravel**](https://github.com/antonioribeiro/google2fa-laravel#readme) package. -> -> For custom configuration like [generating QR-Code using SVG render](https://github.com/antonioribeiro/google2fa-laravel#qrcode-backend) instead of a default Imagemagick, -> you can [publish the default configuration](https://github.com/antonioribeiro/google2fa-laravel#publish-the-config-file) and adjust it as per your needs. - -1. Add file download JS to Mix file - -```js -.copy('vendor/arkecosystem/foundation/resources/assets/js/file-download.js', 'public/js/file-download.js') -``` - -2. Include file on any page that needs it (e.g. Account Settings) - -```blade -@push('scripts') - @vite('resources/js/file-download.js') -@endpush -``` - -3. Build assets - -```bash -yarn prod -``` - -### Nova & Permissions - -1. Install required packages: - -```bash -composer require laravel/nova spatie/laravel-permission="^3.16" vyuldashev/nova-permission -``` - -2. Add or update any policies to extend the base Policy `ARKEcosystem\Foundation\Fortify\Policies\Policy` - -3. Setup Playbooks and extend the DemoPlaybook with additional data the project needs - -4. If extending the UserRole with additional roles, inject the local UserRole to replace the base version - -In `app/App/Providers/AppServiceProvider.php`: - -```php -use ARKEcosystem\Foundation\Fortify\Contracts\UserRole as UserRoleContract; -use App\Support\Enums\UserRole; - -class AppServiceProvider -{ - public function boot(): void - { - ... - - app()->singleton(UserRoleContract::class, UserRole::class); - } -} -``` - -5. Add the Role & Permission policies to the `AuthServiceProvider`: - -```php -use ARKEcosystem\Foundation\Fortify\Models\Permission; -use ARKEcosystem\Foundation\Fortify\Policies\PermissionPolicy; -use ARKEcosystem\Foundation\Fortify\Policies\RolePolicy; -use Spatie\Permission\Models\Role; - -class AuthServiceProvider -{ - protected $policies = [ - Role::class => RolePolicy::class, - Permission::class => PermissionPolicy::class, - ]; -} -``` - -6. Set the Permission model in the `config/permission.php` file: - -```php -'permission' => ARKEcosystem\Foundation\Fortify\Models\Permission::class, -``` - -7. Setup permissions and roles in `database/seeders/app/permissions.json`. Take a look at the [example](/examples/fortify/permissions.json). - -### Required images - -#### Password Confirmation modal - -The password confirmation modal requires an image to be added to to the path `resources/images/auth/confirm-password.svg` for the projects that use it.