From d526a383836312398fc36429c4af1e4ac1b6e03c Mon Sep 17 00:00:00 2001 From: BibaltiK Date: Thu, 5 Feb 2026 17:09:54 +0100 Subject: [PATCH] Core components and identity module outsourced --- bin/migrations.php | 8 +- composer.json | 33 +- composer.lock | 173 +++++- config/autoload/migrations.action.php | 3 +- config/autoload/migrations.develope.php | 3 +- config/autoload/migrations.global.php | 3 +- config/autoload/migrations.testing.php | 3 +- config/config.php | 3 +- config/routes.php | 4 +- ...rsion20231103223745_CreateAccountTable.php | 38 -- ...103224045_CreateAccountAccessAuthTable.php | 37 -- ...103224046_CreateAccountActivationTable.php | 33 -- ...Version20231103224047_CreateTokenTable.php | 34 -- ...ion20260121203207_CreateWorkspaceTable.php | 2 +- public/api/docs/swagger.json | 493 +----------------- src/App/Account/ConfigProvider.php | 17 - .../config/autoload/token.global.php.dist | 20 - .../Account/Identity/src/ConfigProvider.php | 387 -------------- .../Identity/src/DTO/Account/Account.php | 60 --- .../src/DTO/Account/AccountPassword.php | 24 - .../src/DTO/Account/AccountRegistration.php | 29 -- .../Identity/src/DTO/Account/ApiMe.php | 16 - .../src/DTO/Account/AuthenticationRequest.php | 32 -- .../src/DTO/Client/ClientIdentification.php | 17 - .../DTO/Client/ClientIdentificationData.php | 20 - .../Account/Identity/src/DTO/EMail/EMail.php | 24 - .../DTO/Response/AuthenticationResponse.php | 31 -- .../src/DTO/Response/HttpResponseMessage.php | 33 -- .../Identity/src/DTO/Token/AccessToken.php | 24 - .../src/DTO/Token/AccountPasswordToken.php | 24 - .../Identity/src/DTO/Token/JwtTokenConfig.php | 26 - .../Identity/src/DTO/Token/RefreshToken.php | 24 - .../Account/Identity/src/DTO/Token/Token.php | 24 - .../Account/Identity/src/Domain/Account.php | 26 - .../Identity/src/Domain/AccountAccessAuth.php | 24 - .../Domain/AccountAccessAuthCollection.php | 31 -- .../Identity/src/Domain/AccountActivation.php | 23 - .../Domain/AccountActivationCollection.php | 31 -- .../Identity/src/Domain/AccountCollection.php | 31 -- .../Exception/AccountNotFoundException.php | 16 - .../Exception/DuplicateAuthException.php | 17 - .../Exception/DuplicateEMailException.php | 14 - .../InvalidRefreshTokenException.php | 14 - .../Exception/PasswordMismatchException.php | 14 - .../Exception/SecurityBreachException.php | 17 - .../src/Domain/Message/IdentityLogMessage.php | 55 -- .../Domain/Message/IdentityStatusMessage.php | 21 - src/App/Account/Identity/src/Domain/Token.php | 24 - .../Identity/src/Domain/TokenCollection.php | 31 -- .../src/Handler/AccessTokenHandler.php | 55 -- .../src/Handler/AccountActivationHandler.php | 70 --- .../AccountPasswordForgottenHandler.php | 48 -- .../src/Handler/AccountPasswordHandler.php | 66 --- .../src/Handler/AccountRegisterHandler.php | 50 -- .../src/Handler/AuthenticationHandler.php | 63 --- .../Identity/src/Handler/LogoutHandler.php | 75 --- .../Account/AccountAccessAuthHydrator.php | 69 --- .../Account/AccountActivationHydrator.php | 63 --- .../Hydrator/Account/AccountHydrator.php | 76 --- .../Hydrator/Token/TokenHydrator.php | 65 --- .../Account/AccountAccessAuthRepository.php | 71 --- .../Account/AccountActivationRepository.php | 57 -- .../Repository/Account/AccountRepository.php | 58 --- .../Repository/Token/TokenRepository.php | 56 -- .../Table/Account/AccountAccessAuthTable.php | 144 ----- .../Table/Account/AccountActivationTable.php | 106 ---- .../Table/Account/AccountTable.php | 107 ---- .../Persistence/Table/Token/TokenTable.php | 105 ---- .../Account/AccountAuthenticationService.php | 78 --- .../Service/Account/AccountCreatorService.php | 92 ---- .../Account/AccountRegisterService.php | 41 -- .../AccountRegisterServiceInterface.php | 10 - .../Service/Account/AccountService.php | 102 ---- .../Service/Account/PasswordChangeService.php | 60 --- .../Service/Account/PasswordService.php | 33 -- .../Authentication/AuthenticationService.php | 11 - .../ClientIdentificationService.php | 21 - .../Service/Token/AccessTokenService.php | 37 -- .../Token/AccessTokenServiceFactory.php | 17 - .../Service/Token/ActivationTokenService.php | 60 --- .../Token/ActivationTokenServiceFactory.php | 17 - .../Service/Token/PasswordTokenService.php | 64 --- .../Token/PasswordTokenServiceFactory.php | 17 - .../Service/Token/RefreshTokenService.php | 105 ---- .../Token/RefreshTokenServiceFactory.php | 27 - .../Validator/AccountActivationValidator.php | 18 - .../Validator/AuthenticationValidator.php | 18 - .../Infrastructure/Validator/DateLessNow.php | 37 -- .../Validator/Input/AccountNameInput.php | 26 - .../Validator/Input/PasswordInput.php | 26 - .../Validator/PasswordValidator.php | 15 - .../AuthenticationConditionsMiddleware.php | 30 -- .../AuthenticationValidationMiddleware.php | 43 -- .../Account/LastActivityUpdaterMiddleware.php | 48 -- .../RequestAuthenticationMiddleware.php | 76 --- .../ActivationInputValidatorMiddleware.php | 45 -- .../EmailInputValidatorMiddleware.php | 58 --- .../PasswordInputValidatorMiddleware.php | 41 -- .../ClientIdentificationMiddleware.php | 31 -- .../IdentityExceptionMappingMiddleware.php | 87 ---- .../Token/AccessTokenValidationMiddleware.php | 47 -- .../Token/RefreshTokenAccountMiddleware.php | 43 -- ...efreshTokenDatabaseExistenceMiddleware.php | 43 -- ...kenMatchClientIdentificationMiddleware.php | 43 -- .../RefreshTokenValidationMiddleware.php | 40 -- ...efreshTokenViaBodyValidationMiddleware.php | 41 -- src/App/Account/Profile/.gitkeep | 0 src/App/ConfigProvider.php | 2 - .../Mailing/config/autoload/mail.global.dist | 8 - src/App/Mailing/src/ConfigProvider.php | 41 -- src/App/Mailing/src/Domain/EmailType.php | 74 --- .../Exception/InvalidArgumentException.php | 7 - .../src/Infrastructure/EmailService.php | 28 - .../Infrastructure/EmailServiceFactory.php | 18 - .../Validator/EMailValidator.php | 15 - .../Validator/Input/EmailInput.php | 26 - .../Workspace/WorkspaceCreatorInterface.php | 2 +- .../Shared/src/Handler/PingHandler.php | 2 +- .../Shared/src/Handler/SwaggerUIHandler.php | 2 +- src/App/Workspace/src/ConfigProvider.php | 2 +- .../Workspace/src/DTO/WorkspaceResponse.php | 2 +- .../src/Domain/WorkspaceCollection.php | 2 +- .../src/Handler/ListOwnWorkspacesHandler.php | 2 +- .../src/Handler/WorkspaceCreateHandler.php | 2 +- .../Service/WorkspaceCreator.php | 2 +- src/Shared/src/ConfigProvider.php | 56 -- .../AccountAccessAuthCollectionInterface.php | 16 - .../Account/AccountAccessAuthInterface.php | 24 - .../AccountActivationCollectionInterface.php | 16 - .../Account/AccountActivationInterface.php | 20 - .../Account/AccountCollectionInterface.php | 16 - .../Account/AccountCreatorInterface.php | 8 - .../src/Domain/Account/AccountInterface.php | 28 - .../src/Domain/Enum/Account/AccountRoles.php | 23 - .../Enum/Account/AccountVisibleStatus.php | 23 - src/Shared/src/Domain/Enum/DataType.php | 19 - src/Shared/src/Domain/Enum/DateTimeFormat.php | 8 - .../src/Domain/Enum/Router/RouteIdent.php | 9 - .../src/Domain/Enum/Token/TokenType.php | 9 - .../Exception/DuplicateEntryException.php | 18 - .../Domain/Exception/EmptyResultException.php | 9 - .../Exception/HttpDuplicateEntryException.php | 25 - .../src/Domain/Exception/HttpException.php | 44 -- ...ndledInvalidArgumentAsSuccessException.php | 25 - .../HttpInvalidArgumentException.php | 25 - .../Exception/HttpUnauthorizedException.php | 25 - .../Exception/UndefinedOffsetException.php | 9 - .../src/Domain/Mailing/MailerInterface.php | 10 - src/Shared/src/Domain/Message/LogMessage.php | 8 - .../src/Domain/Message/StatusMessage.php | 14 - .../Domain/Token/TokenCollectionInterface.php | 16 - .../src/Domain/Token/TokenInterface.php | 22 - .../Factory/DatabaseFactory.php | 33 -- .../Factory/ErrorResponseFactory.php | 51 -- .../Infrastructure/Factory/MailFactory.php | 19 - .../Infrastructure/Factory/QueryFactory.php | 21 - .../Infrastructure/Factory/UuidFactory.php | 13 - .../AccountAccessAuthHydratorInterface.php | 14 - .../AccountActivationHydratorInterface.php | 14 - .../Account/AccountHydratorInterface.php | 14 - .../Hydrator/HydratorInterface.php | 10 - .../Hydrator/Token/TokenHydratorInterface.php | 14 - .../Infrastructure/Logger/LoggerFactory.php | 67 --- .../Logger/MetaDataProcessor.php | 29 -- .../Persistence/AbstractTable.php | 46 -- .../Contract/TransactionManagerInterface.php | 12 - .../AccountAccessAuthRepositoryInterface.php | 30 -- .../AccountActivationRepositoryInterface.php | 25 - .../Account/AccountRepositoryInterface.php | 26 - .../Repository/RepositoryInterface.php | 8 - .../Token/TokenRepositoryInterface.php | 24 - .../AccountAccessAuthStoreInterface.php | 30 -- .../AccountActivationStoreInterface.php | 25 - .../Store/Account/AccountStoreInterface.php | 26 - .../Persistence/Store/StoreInterface.php | 10 - .../Store/Token/TokenStoreInterface.php | 24 - .../Infrastructure/Service/SlugService.php | 14 - .../Middleware/ApiErrorHandlerMiddleware.php | 27 - .../FluentTransactionMiddleware.php | 48 -- .../src/Middleware/RequireLoginMiddleware.php | 31 -- .../Middleware/RouteNotFoundMiddleware.php | 24 - .../src/Trait/CloneReadonlyClassWith.php | 16 - src/Shared/src/Trait/JwtTokenTrait.php | 42 -- src/Shared/src/Type/TypeInterface.php | 13 - src/Shared/src/Utils/Collectible.php | 7 - src/Shared/src/Utils/Collection.php | 113 ---- src/Shared/src/Utils/CollectionInterface.php | 12 - src/Shared/src/Utils/UuidFactory.php | 7 - src/Shared/src/Utils/UuidFactoryInterface.php | 12 - .../Identity/AccountActivationTest.php | 98 ---- .../Account/Identity/AuthenticationTest.php | 188 ------- .../App/Account/Identity/LogoutTest.php | 120 ----- .../Account/Identity/PasswordChangeTest.php | 99 ---- .../Identity/PasswordForgottenTest.php | 70 --- .../App/Account/Identity/RegisterTest.php | 86 --- .../App/Account/Identity/TokenRefreshTest.php | 119 ----- .../Factory/AccountAccessAuthFactory.php | 2 +- .../Factory/AccountActivationFactory.php | 2 +- .../Identity => }/Factory/AccountFactory.php | 2 +- .../Factory/PasswordChangeFactory.php | 2 +- tests/TestIntegrationCase.php | 2 +- 201 files changed, 216 insertions(+), 7430 deletions(-) delete mode 100644 database/migrations/Version20231103223745_CreateAccountTable.php delete mode 100644 database/migrations/Version20231103224045_CreateAccountAccessAuthTable.php delete mode 100644 database/migrations/Version20231103224046_CreateAccountActivationTable.php delete mode 100644 database/migrations/Version20231103224047_CreateTokenTable.php delete mode 100644 src/App/Account/ConfigProvider.php delete mode 100644 src/App/Account/Identity/config/autoload/token.global.php.dist delete mode 100644 src/App/Account/Identity/src/ConfigProvider.php delete mode 100644 src/App/Account/Identity/src/DTO/Account/Account.php delete mode 100644 src/App/Account/Identity/src/DTO/Account/AccountPassword.php delete mode 100644 src/App/Account/Identity/src/DTO/Account/AccountRegistration.php delete mode 100644 src/App/Account/Identity/src/DTO/Account/ApiMe.php delete mode 100644 src/App/Account/Identity/src/DTO/Account/AuthenticationRequest.php delete mode 100644 src/App/Account/Identity/src/DTO/Client/ClientIdentification.php delete mode 100644 src/App/Account/Identity/src/DTO/Client/ClientIdentificationData.php delete mode 100644 src/App/Account/Identity/src/DTO/EMail/EMail.php delete mode 100644 src/App/Account/Identity/src/DTO/Response/AuthenticationResponse.php delete mode 100644 src/App/Account/Identity/src/DTO/Response/HttpResponseMessage.php delete mode 100644 src/App/Account/Identity/src/DTO/Token/AccessToken.php delete mode 100644 src/App/Account/Identity/src/DTO/Token/AccountPasswordToken.php delete mode 100644 src/App/Account/Identity/src/DTO/Token/JwtTokenConfig.php delete mode 100644 src/App/Account/Identity/src/DTO/Token/RefreshToken.php delete mode 100644 src/App/Account/Identity/src/DTO/Token/Token.php delete mode 100644 src/App/Account/Identity/src/Domain/Account.php delete mode 100644 src/App/Account/Identity/src/Domain/AccountAccessAuth.php delete mode 100644 src/App/Account/Identity/src/Domain/AccountAccessAuthCollection.php delete mode 100644 src/App/Account/Identity/src/Domain/AccountActivation.php delete mode 100644 src/App/Account/Identity/src/Domain/AccountActivationCollection.php delete mode 100644 src/App/Account/Identity/src/Domain/AccountCollection.php delete mode 100644 src/App/Account/Identity/src/Domain/Exception/AccountNotFoundException.php delete mode 100644 src/App/Account/Identity/src/Domain/Exception/DuplicateAuthException.php delete mode 100644 src/App/Account/Identity/src/Domain/Exception/DuplicateEMailException.php delete mode 100644 src/App/Account/Identity/src/Domain/Exception/InvalidRefreshTokenException.php delete mode 100644 src/App/Account/Identity/src/Domain/Exception/PasswordMismatchException.php delete mode 100644 src/App/Account/Identity/src/Domain/Exception/SecurityBreachException.php delete mode 100644 src/App/Account/Identity/src/Domain/Message/IdentityLogMessage.php delete mode 100644 src/App/Account/Identity/src/Domain/Message/IdentityStatusMessage.php delete mode 100644 src/App/Account/Identity/src/Domain/Token.php delete mode 100644 src/App/Account/Identity/src/Domain/TokenCollection.php delete mode 100644 src/App/Account/Identity/src/Handler/AccessTokenHandler.php delete mode 100644 src/App/Account/Identity/src/Handler/AccountActivationHandler.php delete mode 100644 src/App/Account/Identity/src/Handler/AccountPasswordForgottenHandler.php delete mode 100644 src/App/Account/Identity/src/Handler/AccountPasswordHandler.php delete mode 100644 src/App/Account/Identity/src/Handler/AccountRegisterHandler.php delete mode 100644 src/App/Account/Identity/src/Handler/AuthenticationHandler.php delete mode 100644 src/App/Account/Identity/src/Handler/LogoutHandler.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Hydrator/Account/AccountAccessAuthHydrator.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Hydrator/Account/AccountActivationHydrator.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Hydrator/Account/AccountHydrator.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Hydrator/Token/TokenHydrator.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Persistence/Repository/Account/AccountAccessAuthRepository.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Persistence/Repository/Account/AccountActivationRepository.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Persistence/Repository/Account/AccountRepository.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Persistence/Repository/Token/TokenRepository.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Persistence/Table/Account/AccountAccessAuthTable.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Persistence/Table/Account/AccountActivationTable.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Persistence/Table/Account/AccountTable.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Persistence/Table/Token/TokenTable.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Service/Account/AccountAuthenticationService.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Service/Account/AccountCreatorService.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Service/Account/AccountRegisterService.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Service/Account/AccountRegisterServiceInterface.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Service/Account/AccountService.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Service/Account/PasswordChangeService.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Service/Account/PasswordService.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Service/Authentication/AuthenticationService.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Service/ClientIdentification/ClientIdentificationService.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Service/Token/AccessTokenService.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Service/Token/AccessTokenServiceFactory.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Service/Token/ActivationTokenService.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Service/Token/ActivationTokenServiceFactory.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Service/Token/PasswordTokenService.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Service/Token/PasswordTokenServiceFactory.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Service/Token/RefreshTokenService.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Service/Token/RefreshTokenServiceFactory.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Validator/AccountActivationValidator.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Validator/AuthenticationValidator.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Validator/DateLessNow.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Validator/Input/AccountNameInput.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Validator/Input/PasswordInput.php delete mode 100644 src/App/Account/Identity/src/Infrastructure/Validator/PasswordValidator.php delete mode 100644 src/App/Account/Identity/src/Middleware/Account/Authentication/AuthenticationConditionsMiddleware.php delete mode 100644 src/App/Account/Identity/src/Middleware/Account/Authentication/AuthenticationValidationMiddleware.php delete mode 100644 src/App/Account/Identity/src/Middleware/Account/LastActivityUpdaterMiddleware.php delete mode 100644 src/App/Account/Identity/src/Middleware/Account/RequestAuthenticationMiddleware.php delete mode 100644 src/App/Account/Identity/src/Middleware/Account/Validation/ActivationInputValidatorMiddleware.php delete mode 100644 src/App/Account/Identity/src/Middleware/Account/Validation/EmailInputValidatorMiddleware.php delete mode 100644 src/App/Account/Identity/src/Middleware/Account/Validation/PasswordInputValidatorMiddleware.php delete mode 100644 src/App/Account/Identity/src/Middleware/ClientIdentification/ClientIdentificationMiddleware.php delete mode 100644 src/App/Account/Identity/src/Middleware/IdentityExceptionMappingMiddleware.php delete mode 100644 src/App/Account/Identity/src/Middleware/Token/AccessTokenValidationMiddleware.php delete mode 100644 src/App/Account/Identity/src/Middleware/Token/RefreshTokenAccountMiddleware.php delete mode 100644 src/App/Account/Identity/src/Middleware/Token/RefreshTokenDatabaseExistenceMiddleware.php delete mode 100644 src/App/Account/Identity/src/Middleware/Token/RefreshTokenMatchClientIdentificationMiddleware.php delete mode 100644 src/App/Account/Identity/src/Middleware/Token/RefreshTokenValidationMiddleware.php delete mode 100644 src/App/Account/Identity/src/Middleware/Token/RefreshTokenViaBodyValidationMiddleware.php delete mode 100644 src/App/Account/Profile/.gitkeep delete mode 100644 src/App/Mailing/config/autoload/mail.global.dist delete mode 100644 src/App/Mailing/src/ConfigProvider.php delete mode 100644 src/App/Mailing/src/Domain/EmailType.php delete mode 100644 src/App/Mailing/src/Exception/InvalidArgumentException.php delete mode 100644 src/App/Mailing/src/Infrastructure/EmailService.php delete mode 100644 src/App/Mailing/src/Infrastructure/EmailServiceFactory.php delete mode 100644 src/App/Mailing/src/Infrastructure/Validator/EMailValidator.php delete mode 100644 src/App/Mailing/src/Infrastructure/Validator/Input/EmailInput.php rename src/{ => App}/Shared/src/Handler/PingHandler.php (97%) rename src/{ => App}/Shared/src/Handler/SwaggerUIHandler.php (97%) delete mode 100644 src/Shared/src/ConfigProvider.php delete mode 100644 src/Shared/src/Domain/Account/AccountAccessAuthCollectionInterface.php delete mode 100644 src/Shared/src/Domain/Account/AccountAccessAuthInterface.php delete mode 100644 src/Shared/src/Domain/Account/AccountActivationCollectionInterface.php delete mode 100644 src/Shared/src/Domain/Account/AccountActivationInterface.php delete mode 100644 src/Shared/src/Domain/Account/AccountCollectionInterface.php delete mode 100644 src/Shared/src/Domain/Account/AccountCreatorInterface.php delete mode 100644 src/Shared/src/Domain/Account/AccountInterface.php delete mode 100644 src/Shared/src/Domain/Enum/Account/AccountRoles.php delete mode 100644 src/Shared/src/Domain/Enum/Account/AccountVisibleStatus.php delete mode 100644 src/Shared/src/Domain/Enum/DataType.php delete mode 100644 src/Shared/src/Domain/Enum/DateTimeFormat.php delete mode 100644 src/Shared/src/Domain/Enum/Router/RouteIdent.php delete mode 100644 src/Shared/src/Domain/Enum/Token/TokenType.php delete mode 100644 src/Shared/src/Domain/Exception/DuplicateEntryException.php delete mode 100644 src/Shared/src/Domain/Exception/EmptyResultException.php delete mode 100644 src/Shared/src/Domain/Exception/HttpDuplicateEntryException.php delete mode 100644 src/Shared/src/Domain/Exception/HttpException.php delete mode 100644 src/Shared/src/Domain/Exception/HttpHandledInvalidArgumentAsSuccessException.php delete mode 100644 src/Shared/src/Domain/Exception/HttpInvalidArgumentException.php delete mode 100644 src/Shared/src/Domain/Exception/HttpUnauthorizedException.php delete mode 100644 src/Shared/src/Domain/Exception/UndefinedOffsetException.php delete mode 100644 src/Shared/src/Domain/Mailing/MailerInterface.php delete mode 100644 src/Shared/src/Domain/Message/LogMessage.php delete mode 100644 src/Shared/src/Domain/Message/StatusMessage.php delete mode 100644 src/Shared/src/Domain/Token/TokenCollectionInterface.php delete mode 100644 src/Shared/src/Domain/Token/TokenInterface.php delete mode 100644 src/Shared/src/Infrastructure/Factory/DatabaseFactory.php delete mode 100644 src/Shared/src/Infrastructure/Factory/ErrorResponseFactory.php delete mode 100644 src/Shared/src/Infrastructure/Factory/MailFactory.php delete mode 100644 src/Shared/src/Infrastructure/Factory/QueryFactory.php delete mode 100644 src/Shared/src/Infrastructure/Factory/UuidFactory.php delete mode 100644 src/Shared/src/Infrastructure/Hydrator/Account/AccountAccessAuthHydratorInterface.php delete mode 100644 src/Shared/src/Infrastructure/Hydrator/Account/AccountActivationHydratorInterface.php delete mode 100644 src/Shared/src/Infrastructure/Hydrator/Account/AccountHydratorInterface.php delete mode 100644 src/Shared/src/Infrastructure/Hydrator/HydratorInterface.php delete mode 100644 src/Shared/src/Infrastructure/Hydrator/Token/TokenHydratorInterface.php delete mode 100644 src/Shared/src/Infrastructure/Logger/LoggerFactory.php delete mode 100644 src/Shared/src/Infrastructure/Logger/MetaDataProcessor.php delete mode 100644 src/Shared/src/Infrastructure/Persistence/AbstractTable.php delete mode 100644 src/Shared/src/Infrastructure/Persistence/Contract/TransactionManagerInterface.php delete mode 100644 src/Shared/src/Infrastructure/Persistence/Repository/Account/AccountAccessAuthRepositoryInterface.php delete mode 100644 src/Shared/src/Infrastructure/Persistence/Repository/Account/AccountActivationRepositoryInterface.php delete mode 100644 src/Shared/src/Infrastructure/Persistence/Repository/Account/AccountRepositoryInterface.php delete mode 100644 src/Shared/src/Infrastructure/Persistence/Repository/RepositoryInterface.php delete mode 100644 src/Shared/src/Infrastructure/Persistence/Repository/Token/TokenRepositoryInterface.php delete mode 100644 src/Shared/src/Infrastructure/Persistence/Store/Account/AccountAccessAuthStoreInterface.php delete mode 100644 src/Shared/src/Infrastructure/Persistence/Store/Account/AccountActivationStoreInterface.php delete mode 100644 src/Shared/src/Infrastructure/Persistence/Store/Account/AccountStoreInterface.php delete mode 100644 src/Shared/src/Infrastructure/Persistence/Store/StoreInterface.php delete mode 100644 src/Shared/src/Infrastructure/Persistence/Store/Token/TokenStoreInterface.php delete mode 100644 src/Shared/src/Infrastructure/Service/SlugService.php delete mode 100644 src/Shared/src/Middleware/ApiErrorHandlerMiddleware.php delete mode 100644 src/Shared/src/Middleware/FluentTransactionMiddleware.php delete mode 100644 src/Shared/src/Middleware/RequireLoginMiddleware.php delete mode 100644 src/Shared/src/Middleware/RouteNotFoundMiddleware.php delete mode 100644 src/Shared/src/Trait/CloneReadonlyClassWith.php delete mode 100644 src/Shared/src/Trait/JwtTokenTrait.php delete mode 100644 src/Shared/src/Type/TypeInterface.php delete mode 100644 src/Shared/src/Utils/Collectible.php delete mode 100644 src/Shared/src/Utils/Collection.php delete mode 100644 src/Shared/src/Utils/CollectionInterface.php delete mode 100644 src/Shared/src/Utils/UuidFactory.php delete mode 100644 src/Shared/src/Utils/UuidFactoryInterface.php delete mode 100644 tests/Integration/App/Account/Identity/AccountActivationTest.php delete mode 100644 tests/Integration/App/Account/Identity/AuthenticationTest.php delete mode 100644 tests/Integration/App/Account/Identity/LogoutTest.php delete mode 100644 tests/Integration/App/Account/Identity/PasswordChangeTest.php delete mode 100644 tests/Integration/App/Account/Identity/PasswordForgottenTest.php delete mode 100644 tests/Integration/App/Account/Identity/RegisterTest.php delete mode 100644 tests/Integration/App/Account/Identity/TokenRefreshTest.php rename tests/Integration/App/{Account/Identity => }/Factory/AccountAccessAuthFactory.php (94%) rename tests/Integration/App/{Account/Identity => }/Factory/AccountActivationFactory.php (94%) rename tests/Integration/App/{Account/Identity => }/Factory/AccountFactory.php (94%) rename tests/Integration/App/{Account/Identity => }/Factory/PasswordChangeFactory.php (93%) diff --git a/bin/migrations.php b/bin/migrations.php index cef980d9..ad1cd720 100755 --- a/bin/migrations.php +++ b/bin/migrations.php @@ -12,7 +12,7 @@ use Doctrine\Migrations\Tools\Console\Command; use Symfony\Component\Console\Application; -$env = getenv('APP_ENV') ?: ''; +$env = getenv('APP_ENV') ?? 'global'; $dbParams = (require realpath(__DIR__) . sprintf('/../config/autoload/database.%s.php', $env))['database']; $dbParams['driver'] = 'pdo_' . $dbParams['driver']; @@ -25,10 +25,10 @@ $configuration->setCustomTemplate(__DIR__ . '/../config/migrations.template.tpl'); -$configuration->addMigrationsDirectory('Migrations', $config['migrations_paths']['Migrations']); -if (array_key_exists('TestDataMigrations', $config['migrations_paths'])) { - $configuration->addMigrationsDirectory('TestDataMigrations', $config['migrations_paths']['TestDataMigrations']); +foreach ($config['migrations_paths'] as $key => $path) { + $configuration->addMigrationsDirectory($key, $path); } + $configuration->setAllOrNothing($config['all_or_nothing']); $configuration->setCheckDatabasePlatform($config['check_database_platform']); $configuration->setTransactional($config['transactional']); diff --git a/composer.json b/composer.json index 4f1a864f..218140b8 100644 --- a/composer.json +++ b/composer.json @@ -41,26 +41,8 @@ "ext-json": "*", "ext-openssl": "*", "ext-pdo": "*", - "envms/fluentpdo": "^2.2", - "firebase/php-jwt": "^6.0", - "laminas/laminas-config-aggregator": "^1.6", - "laminas/laminas-diactoros": "^3.8.0", - "laminas/laminas-inputfilter": "^2.30", - "laminas/laminas-servicemanager": "^3.4", - "laminas/laminas-stdlib": "^3.6", - "laminas/laminas-validator": "^2.64", - "laminas/laminas-component-installer": "^2.6 || ^3.0", - "laminas/laminas-development-mode": "^3.3.0", - "mezzio/mezzio-tooling": "^2.12", - "mezzio/mezzio": "^3", - "mezzio/mezzio-cors": "^1.13", - "mezzio/mezzio-fastroute": "^3.0.3", - "mezzio/mezzio-helpers": "^5.7", - "monolog/monolog": "^3.9.0", - "ramsey/uuid": "^4.7", - "symfony/mailer": "^6.4", - "zircote/swagger-php": "^6", - "jetbrains/phpstorm-attributes": "^1.0" + "exdrals/core": "^0.1.0", + "exdrals/identity": "^0.1.0" }, "require-dev": { "dealerdirect/phpcodesniffer-composer-installer": "^1.2", @@ -82,13 +64,10 @@ }, "autoload": { "psr-4": { - "ownHackathon\\" : "src/App/", - "ownHackathon\\Shared\\" : "src/App/Shared/src/", - "ownHackathon\\Account\\" : "src/App/Account/", - "ownHackathon\\Workspace\\" : "src/App/Workspace/src/", - "Exdrals\\Shared\\": "src/Shared/src", - "Exdrals\\Identity\\" : "src/App/Account/Identity/src/", - "Exdrals\\Mailing\\" : "src/App/Mailing/src/" + "ownHackathon\\": "src/App/", + "ownHackathon\\Shared\\": "src/App/Shared/src/", + "ownHackathon\\Account\\": "src/App/Account/", + "ownHackathon\\Workspace\\": "src/App/Workspace/src/" } }, "autoload-dev": { diff --git a/composer.lock b/composer.lock index a0ad606f..56c185d7 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b5d9ef0b441a66ec0eb67bdb20fba3b6", + "content-hash": "497bea8a3045e06d048ba8897d7f5f9b", "packages": [ { "name": "brick/math", - "version": "0.14.5", + "version": "0.14.6", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "618a8077b3c326045e10d5788ed713b341fcfe40" + "reference": "32498d5e1897e7642c0b961ace2df6d7dc9a3bc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/618a8077b3c326045e10d5788ed713b341fcfe40", - "reference": "618a8077b3c326045e10d5788ed713b341fcfe40", + "url": "https://api.github.com/repos/brick/math/zipball/32498d5e1897e7642c0b961ace2df6d7dc9a3bc3", + "reference": "32498d5e1897e7642c0b961ace2df6d7dc9a3bc3", "shasum": "" }, "require": { @@ -56,7 +56,7 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.14.5" + "source": "https://github.com/brick/math/tree/0.14.6" }, "funding": [ { @@ -64,7 +64,7 @@ "type": "github" } ], - "time": "2026-02-03T18:06:51+00:00" + "time": "2026-02-05T07:59:58+00:00" }, { "name": "brick/varexporter", @@ -317,6 +317,155 @@ }, "time": "2022-01-27T21:49:44+00:00" }, + { + "name": "exdrals/core", + "version": "v0.1.4", + "source": { + "type": "git", + "url": "https://github.com/Exdrals/core.git", + "reference": "14f6b2ad9811aba648be442bf3971cf7e7afbd36" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Exdrals/core/zipball/14f6b2ad9811aba648be442bf3971cf7e7afbd36", + "reference": "14f6b2ad9811aba648be442bf3971cf7e7afbd36", + "shasum": "" + }, + "require": { + "envms/fluentpdo": "^2.2", + "ext-json": "*", + "ext-openssl": "*", + "ext-pdo": "*", + "firebase/php-jwt": "^6.0", + "jetbrains/phpstorm-attributes": "^1.0", + "laminas/laminas-component-installer": "^2.6 || ^3.0", + "laminas/laminas-config-aggregator": "^1.6", + "laminas/laminas-development-mode": "^3.3.0", + "laminas/laminas-diactoros": "^3.8.0", + "laminas/laminas-inputfilter": "^2.30", + "laminas/laminas-servicemanager": "^3.4", + "laminas/laminas-stdlib": "^3.6", + "laminas/laminas-validator": "^2.64", + "mezzio/mezzio": "^3", + "mezzio/mezzio-cors": "^1.13", + "mezzio/mezzio-fastroute": "^3.0.3", + "mezzio/mezzio-helpers": "^5.7", + "mezzio/mezzio-tooling": "^2.12", + "monolog/monolog": "^3.9.0", + "php": "^8.4.0", + "ramsey/uuid": "^4.7", + "symfony/mailer": "^6.4", + "zircote/swagger-php": "^6" + }, + "type": "library", + "extra": { + "laminas": { + "component-auto-installs": [ + "mezzio/mezzio", + "mezzio/mezzio-helpers", + "mezzio/mezzio-router", + "laminas/laminas-httphandlerrunner", + "mezzio/mezzio-fastroute" + ] + } + }, + "autoload": { + "psr-4": { + "Exdrals\\Core\\": "src/", + "Exdrals\\Token\\": "src/Token/src/", + "Exdrals\\Shared\\": "src/Shared/src", + "Exdrals\\Mailing\\": "src/Mailing/src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "core library for personal projects", + "homepage": "https://github.com/exdrals", + "keywords": [ + "opensource" + ], + "support": { + "docs": "https://github.com/exdrals/core", + "issues": "https://github.com/exdrals/core/issues", + "source": "https://github.com/exdrals/core" + }, + "time": "2026-02-05T22:49:44+00:00" + }, + { + "name": "exdrals/identity", + "version": "v0.1.5", + "source": { + "type": "git", + "url": "https://github.com/Exdrals/identity.git", + "reference": "e33be562269cc5bc76dbfdd6a9c0b75ebe551737" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Exdrals/identity/zipball/e33be562269cc5bc76dbfdd6a9c0b75ebe551737", + "reference": "e33be562269cc5bc76dbfdd6a9c0b75ebe551737", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-openssl": "*", + "ext-pdo": "*", + "php": "~8.4.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^1.2", + "doctrine/migrations": "^3.6", + "exdrals/core": "^0", + "fakerphp/faker": "^1.24", + "filp/whoops": "^2.7.1", + "helmich/phpunit-json-assert": "^3.5", + "helmich/phpunit-psr7-assert": "^4.4", + "mockery/mockery": "^1.6", + "overtrue/phplint": "^9.0", + "pestphp/pest": "^v3.7", + "phpstan/phpstan": "^2.1.33", + "phpstan/phpstan-deprecation-rules": "^2.0.3", + "phpunit/php-code-coverage": "^11.0.0", + "phpunit/phpunit": "^11.5.0", + "roave/security-advisories": "dev-master", + "slevomat/coding-standard": "^8.15", + "squizlabs/php_codesniffer": "^4.0" + }, + "type": "library", + "extra": { + "laminas": { + "component-auto-installs": [ + "mezzio/mezzio", + "mezzio/mezzio-helpers", + "mezzio/mezzio-router", + "laminas/laminas-httphandlerrunner", + "mezzio/mezzio-fastroute" + ] + } + }, + "autoload": { + "psr-4": { + "Exdrals\\Identity\\": "src/Identity/src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "offers authentication for personal projects", + "homepage": "https://github.com/exdrals", + "keywords": [ + "hackathon", + "opensource" + ], + "support": { + "docs": "https://github.com/exdrals/identity", + "issues": "https://github.com/exdrals/identity/issues", + "source": "https://github.com/exdrals/identity" + }, + "time": "2026-02-05T23:39:43+00:00" + }, { "name": "fig/http-message-util", "version": "1.1.5", @@ -7301,12 +7450,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "258cd5fdcb59c29f421927b2cf77f48de9458a98" + "reference": "7ea2d110787f6807213e27a1255c6b858ad99d89" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/258cd5fdcb59c29f421927b2cf77f48de9458a98", - "reference": "258cd5fdcb59c29f421927b2cf77f48de9458a98", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/7ea2d110787f6807213e27a1255c6b858ad99d89", + "reference": "7ea2d110787f6807213e27a1255c6b858ad99d89", "shasum": "" }, "conflict": { @@ -7786,7 +7935,7 @@ "microsoft/microsoft-graph": ">=1.16,<1.109.1|>=2,<2.0.1", "microsoft/microsoft-graph-beta": "<2.0.1", "microsoft/microsoft-graph-core": "<2.0.2", - "microweber/microweber": "<=2.0.19", + "microweber/microweber": "<2.0.20", "mikehaertl/php-shellcommand": "<1.6.1", "mineadmin/mineadmin": "<=3.0.9", "miniorange/miniorange-saml": "<1.4.3", @@ -8311,7 +8460,7 @@ "type": "tidelift" } ], - "time": "2026-02-04T22:06:32+00:00" + "time": "2026-02-05T22:08:29+00:00" }, { "name": "sebastian/cli-parser", diff --git a/config/autoload/migrations.action.php b/config/autoload/migrations.action.php index 0626d103..156310ad 100644 --- a/config/autoload/migrations.action.php +++ b/config/autoload/migrations.action.php @@ -11,7 +11,8 @@ ], 'migrations_paths' => [ - 'Migrations' => __DIR__ . '/../../database/migrations', + 'Exdrals\\Identity\\Migrations' => 'vendor/exdrals/identity/database/migrations', + 'ownHackathon\\Migrations' => 'database/migrations', ], 'all_or_nothing' => true, diff --git a/config/autoload/migrations.develope.php b/config/autoload/migrations.develope.php index 0626d103..156310ad 100644 --- a/config/autoload/migrations.develope.php +++ b/config/autoload/migrations.develope.php @@ -11,7 +11,8 @@ ], 'migrations_paths' => [ - 'Migrations' => __DIR__ . '/../../database/migrations', + 'Exdrals\\Identity\\Migrations' => 'vendor/exdrals/identity/database/migrations', + 'ownHackathon\\Migrations' => 'database/migrations', ], 'all_or_nothing' => true, diff --git a/config/autoload/migrations.global.php b/config/autoload/migrations.global.php index 0626d103..156310ad 100644 --- a/config/autoload/migrations.global.php +++ b/config/autoload/migrations.global.php @@ -11,7 +11,8 @@ ], 'migrations_paths' => [ - 'Migrations' => __DIR__ . '/../../database/migrations', + 'Exdrals\\Identity\\Migrations' => 'vendor/exdrals/identity/database/migrations', + 'ownHackathon\\Migrations' => 'database/migrations', ], 'all_or_nothing' => true, diff --git a/config/autoload/migrations.testing.php b/config/autoload/migrations.testing.php index 0626d103..156310ad 100644 --- a/config/autoload/migrations.testing.php +++ b/config/autoload/migrations.testing.php @@ -11,7 +11,8 @@ ], 'migrations_paths' => [ - 'Migrations' => __DIR__ . '/../../database/migrations', + 'Exdrals\\Identity\\Migrations' => 'vendor/exdrals/identity/database/migrations', + 'ownHackathon\\Migrations' => 'database/migrations', ], 'all_or_nothing' => true, diff --git a/config/config.php b/config/config.php index d3216a54..0e7a0589 100644 --- a/config/config.php +++ b/config/config.php @@ -34,7 +34,8 @@ class_exists(\Mezzio\Swoole\ConfigProvider::class) }, // Default App module config \ownHackathon\ConfigProvider::class, - \Exdrals\Shared\ConfigProvider::class, + \Exdrals\Core\ConfigProvider::class, + \Exdrals\Identity\ConfigProvider::class, // Load application config in a pre-defined order in such a way that local settings // overwrite global settings. (Loaded as first to last): diff --git a/config/routes.php b/config/routes.php index 65808264..4f1363e1 100644 --- a/config/routes.php +++ b/config/routes.php @@ -3,9 +3,9 @@ use Exdrals\Shared\Domain\Enum\Router\RouteIdent; use Mezzio\Application; use Mezzio\MiddlewareFactory; +use ownHackathon\Shared\Handler\PingHandler; +use ownHackathon\Shared\Handler\SwaggerUIHandler; use Psr\Container\ContainerInterface; -use Exdrals\Shared\Handler\PingHandler; -use Exdrals\Shared\Handler\SwaggerUIHandler; return static function (Application $app, MiddlewareFactory $factory, ContainerInterface $container): void { $app->get( diff --git a/database/migrations/Version20231103223745_CreateAccountTable.php b/database/migrations/Version20231103223745_CreateAccountTable.php deleted file mode 100644 index 9f509566..00000000 --- a/database/migrations/Version20231103223745_CreateAccountTable.php +++ /dev/null @@ -1,38 +0,0 @@ -createTable('Account'); - - $table->addColumn('id', Types::INTEGER, ['autoincrement' => true, 'unsigned' => true,]); - $table->addColumn('uuid', Types::GUID, ); - $table->addColumn('name', Types::STRING, ['length' => 64, 'notnull' => false,]); - $table->addColumn('password', Types::STRING, ['length' => 255, 'notnull' => false,]); - $table->addColumn('email', Types::STRING, ['length' => 512,]); - $table->addColumn('registeredAt', Types::DATETIME_IMMUTABLE, ['default' => 'CURRENT_TIMESTAMP',]); - $table->addColumn('lastActionAt', Types::DATETIME_IMMUTABLE, ['default' => 'CURRENT_TIMESTAMP',]); - - $table->addPrimaryKeyConstraint( - PrimaryKeyConstraint::editor() - ->setUnquotedColumnNames('id') - ->create() - ); - $table->addUniqueIndex(['uuid'], 'account_uuid_UNIQUE'); - $table->addUniqueIndex(['name'], 'account_name_UNIQUE'); - $table->addUniqueIndex(['email'], 'account_email_UNIQUE'); - } - - public function down(Schema $schema): void - { - $schema->dropTable('Account'); - } -} diff --git a/database/migrations/Version20231103224045_CreateAccountAccessAuthTable.php b/database/migrations/Version20231103224045_CreateAccountAccessAuthTable.php deleted file mode 100644 index 89012faa..00000000 --- a/database/migrations/Version20231103224045_CreateAccountAccessAuthTable.php +++ /dev/null @@ -1,37 +0,0 @@ -createTable('AccountAccessAuth'); - - $table->addColumn('id', Types::INTEGER, ['autoincrement' => true, 'unsigned' => true,]); - $table->addColumn('accountId', Types::INTEGER, ['unsigned' => true,]); - $table->addColumn('label', Types::STRING, ['length' => 64, 'default' => 'default']); - $table->addColumn('refreshToken', Types::STRING, ['length' => 512,]); - $table->addColumn('userAgent', Types::STRING, ['length' => 255, 'default' => 'unknown']); - $table->addColumn('clientIdentHash', Types::STRING, ['length' => 128,]); - $table->addColumn('createdAt', Types::DATETIME_IMMUTABLE, ['default' => 'CURRENT_TIMESTAMP',]); - - $table->addPrimaryKeyConstraint( - PrimaryKeyConstraint::editor() - ->setUnquotedColumnNames('id') - ->create() - ); - $table->addUniqueIndex(['refreshToken'], 'account_access_auth_refresh_token_UNIQUE'); - $table->addUniqueIndex(['clientIdentHash'], 'account_access_auth_client_ident_hash_UNIQUE'); - } - - public function down(Schema $schema): void - { - $schema->dropTable('AccountAccessAuth'); - } -} diff --git a/database/migrations/Version20231103224046_CreateAccountActivationTable.php b/database/migrations/Version20231103224046_CreateAccountActivationTable.php deleted file mode 100644 index c8d05e06..00000000 --- a/database/migrations/Version20231103224046_CreateAccountActivationTable.php +++ /dev/null @@ -1,33 +0,0 @@ -createTable('AccountActivation'); - - $table->addColumn('id', Types::INTEGER, ['autoincrement' => true, 'unsigned' => true,]); - $table->addColumn('email', Types::STRING, ['length' => 512,]); - $table->addColumn('token', Types::GUID, ); - $table->addColumn('createdAt', Types::DATETIME_IMMUTABLE, ['default' => 'CURRENT_TIMESTAMP',]); - - $table->addPrimaryKeyConstraint( - PrimaryKeyConstraint::editor() - ->setUnquotedColumnNames('id') - ->create() - ); - $table->addUniqueIndex(['token'], 'account_activation_token_UNIQUE'); - } - - public function down(Schema $schema): void - { - $schema->dropTable('AccountActivation'); - } -} diff --git a/database/migrations/Version20231103224047_CreateTokenTable.php b/database/migrations/Version20231103224047_CreateTokenTable.php deleted file mode 100644 index f282552d..00000000 --- a/database/migrations/Version20231103224047_CreateTokenTable.php +++ /dev/null @@ -1,34 +0,0 @@ -createTable('Token'); - - $table->addColumn('id', Types::INTEGER, ['autoincrement' => true, 'unsigned' => true,]); - $table->addColumn('accountId', Types::INTEGER, ['unsigned' => true,]); - $table->addColumn('token', Types::GUID, ); - $table->addColumn('tokenType', Types::SMALLINT, ['unsigned' => true, 'length' => 2,]); - $table->addColumn('createdAt', Types::DATETIME_IMMUTABLE, ['default' => 'CURRENT_TIMESTAMP',]); - - $table->addPrimaryKeyConstraint( - PrimaryKeyConstraint::editor() - ->setUnquotedColumnNames('id') - ->create() - ); - $table->addUniqueIndex(['token'], 'token_token_UNIQUE'); - } - - public function down(Schema $schema): void - { - $schema->dropTable('Token'); - } -} diff --git a/database/migrations/Version20260121203207_CreateWorkspaceTable.php b/database/migrations/Version20260121203207_CreateWorkspaceTable.php index ef32825e..2cd84c4e 100644 --- a/database/migrations/Version20260121203207_CreateWorkspaceTable.php +++ b/database/migrations/Version20260121203207_CreateWorkspaceTable.php @@ -1,6 +1,6 @@ getMergedConfig(); - } -} diff --git a/src/App/Account/Identity/config/autoload/token.global.php.dist b/src/App/Account/Identity/config/autoload/token.global.php.dist deleted file mode 100644 index ac8d71d3..00000000 --- a/src/App/Account/Identity/config/autoload/token.global.php.dist +++ /dev/null @@ -1,20 +0,0 @@ - [ - 'refresh' => [ - 'key' => 'token secret', - 'algorithmus' => 'HS512', - 'duration' => 60 * 60 * 24 * 7 * 12, - 'iss' => 'Issuer of the token', - 'aud' => 'recipients of the token', - ], - 'access' => [ - 'key' =>'token secret', - 'algorithmus' => 'HS512', - 'duration' => 60 * 5, - 'iss' => 'Issuer of the token', - 'aud' => 'recipients of the token', - ], - ], -]; diff --git a/src/App/Account/Identity/src/ConfigProvider.php b/src/App/Account/Identity/src/ConfigProvider.php deleted file mode 100644 index 0e8d67d9..00000000 --- a/src/App/Account/Identity/src/ConfigProvider.php +++ /dev/null @@ -1,387 +0,0 @@ - $this->getRoutes(), - 'dependencies' => $this->getDependencies(), - ConfigAbstractFactory::class => $this->getAbstractFactoryConfig(), - ]; - } - - public function getRoutes(): array - { - return [ - [ - 'path' => '/api/account[/]', - 'allowed_methods' => ['POST'], - 'middleware' => [ - Middleware\IdentityExceptionMappingMiddleware::class, - Middleware\Account\Validation\EmailInputValidatorMiddleware::class, - Handler\AccountRegisterHandler::class, - ], - 'name' => 'api_identity_register', - ], - [ - 'path' => '/api/account/activation/[{token}[/]]', - 'allowed_methods' => ['POST'], - 'middleware' => [ - Middleware\IdentityExceptionMappingMiddleware::class, - Middleware\Account\Validation\ActivationInputValidatorMiddleware::class, - FluentTransactionMiddleware::class, - Handler\AccountActivationHandler::class, - ], - 'name' => 'api_identity_activation', - ], - - [ - 'path' => '/api/account/authentication[/]', - 'allowed_methods' => ['POST'], - 'middleware' => [ - Middleware\IdentityExceptionMappingMiddleware::class, - Middleware\Account\Authentication\AuthenticationConditionsMiddleware::class, - Middleware\Account\Authentication\AuthenticationValidationMiddleware::class, - Handler\AuthenticationHandler::class, - ], - 'name' => 'api_identity_authentication', - ], - [ - 'path' => '/api/token/refresh[/]', - 'allowed_methods' => ['GET'], - 'middleware' => [ - Middleware\IdentityExceptionMappingMiddleware::class, - Middleware\Token\RefreshTokenValidationMiddleware::class, - Handler\AccessTokenHandler::class, - ], - 'name' => 'api_identity_token_refresh', - ], - - [ - 'path' => '/api/account/password/forgotten[/]', - 'allowed_methods' => ['POST'], - 'middleware' => [ - Middleware\IdentityExceptionMappingMiddleware::class, - Middleware\Account\Validation\EmailInputValidatorMiddleware::class, - Handler\AccountPasswordForgottenHandler::class, - ], - 'name' => 'api_identity_password_forgotten', - ], - [ - 'path' => '/api/account/password/[{token}[/]]', - 'allowed_methods' => ['PATCH'], - 'middleware' => [ - Middleware\IdentityExceptionMappingMiddleware::class, - Middleware\Account\Validation\PasswordInputValidatorMiddleware::class, - Handler\AccountPasswordHandler::class, - ], - 'name' => 'api_identity_password_change', - ], - - [ - 'path' => '/api/account/logout[/]', - 'allowed_methods' => ['POST'], - 'middleware' => [ - Middleware\IdentityExceptionMappingMiddleware::class, - RequireLoginMiddleware::class, - Middleware\Token\AccessTokenValidationMiddleware::class, - Middleware\Token\RefreshTokenViaBodyValidationMiddleware::class, - Handler\LogoutHandler::class, - ], - 'name' => 'api_identity_logout', - ], - [ - 'path' => '/api/account/[{accountUuid:[0-9a-fA-F\-]+}[/]]', - 'allowed_methods' => ['GET'], - 'middleware' => [ - Middleware\IdentityExceptionMappingMiddleware::class, - RequireLoginMiddleware::class, - ], - 'name' => 'api_account_detail', - ], - ]; - } - - public function getDependencies(): array - { - return [ - 'aliases' => [ - AccountAccessAuthHydratorInterface::class => Infrastructure\Hydrator\Account\AccountAccessAuthHydrator::class, - AccountActivationHydratorInterface::class => Infrastructure\Hydrator\Account\AccountActivationHydrator::class, - AccountHydratorInterface::class => Infrastructure\Hydrator\Account\AccountHydrator::class, - TokenHydratorInterface::class => Infrastructure\Hydrator\Token\TokenHydrator::class, - - AccountRepositoryInterface::class => Infrastructure\Persistence\Repository\Account\AccountRepository::class, - AccountActivationRepositoryInterface::class => Infrastructure\Persistence\Repository\Account\AccountActivationRepository::class, - AccountAccessAuthRepositoryInterface::class => Infrastructure\Persistence\Repository\Account\AccountAccessAuthRepository::class, - TokenRepositoryInterface::class => Infrastructure\Persistence\Repository\Token\TokenRepository::class, - AccountStoreInterface::class => Infrastructure\Persistence\Table\Account\AccountTable::class, - AccountAccessAuthStoreInterface::class => Infrastructure\Persistence\Table\Account\AccountAccessAuthTable::class, - AccountActivationStoreInterface::class => Infrastructure\Persistence\Table\Account\AccountActivationTable::class, - TokenStoreInterface::class => Infrastructure\Persistence\Table\Token\TokenTable::class, - ], - 'invokables' => [ - ], - 'factories' => [ - Infrastructure\Hydrator\Account\AccountAccessAuthHydrator::class => InvokableFactory::class, - Infrastructure\Hydrator\Account\AccountActivationHydrator::class => ConfigAbstractFactory::class, - Infrastructure\Hydrator\Account\AccountHydrator::class => ConfigAbstractFactory::class, - Infrastructure\Hydrator\Token\TokenHydrator::class => ConfigAbstractFactory::class, - Middleware\Account\Authentication\AuthenticationConditionsMiddleware::class => InvokableFactory::class, - Middleware\Account\Authentication\AuthenticationValidationMiddleware::class => ConfigAbstractFactory::class, - Middleware\Account\Validation\ActivationInputValidatorMiddleware::class => ConfigAbstractFactory::class, - Middleware\Account\Validation\EmailInputValidatorMiddleware::class => ConfigAbstractFactory::class, - Middleware\Account\Validation\PasswordInputValidatorMiddleware::class => ConfigAbstractFactory::class, - Middleware\Account\LastActivityUpdaterMiddleware::class => ConfigAbstractFactory::class, - Infrastructure\Service\Account\PasswordChangeService::class => ConfigAbstractFactory::class, - Middleware\Account\RequestAuthenticationMiddleware::class => ConfigAbstractFactory::class, - Middleware\ClientIdentification\ClientIdentificationMiddleware::class => ConfigAbstractFactory::class, - Middleware\Token\AccessTokenValidationMiddleware::class => ConfigAbstractFactory::class, - Middleware\Token\RefreshTokenAccountMiddleware::class => ConfigAbstractFactory::class, - Middleware\Token\RefreshTokenDatabaseExistenceMiddleware::class => ConfigAbstractFactory::class, - Middleware\Token\RefreshTokenMatchClientIdentificationMiddleware::class => InvokableFactory::class, - Middleware\Token\RefreshTokenValidationMiddleware::class => ConfigAbstractFactory::class, - Middleware\Token\RefreshTokenViaBodyValidationMiddleware::class => ConfigAbstractFactory::class, - Infrastructure\Persistence\Repository\Account\AccountAccessAuthRepository::class => ConfigAbstractFactory::class, - Infrastructure\Persistence\Repository\Account\AccountActivationRepository::class => ConfigAbstractFactory::class, - Infrastructure\Persistence\Repository\Account\AccountRepository::class => ConfigAbstractFactory::class, - Infrastructure\Persistence\Repository\Token\TokenRepository::class => ConfigAbstractFactory::class, - Infrastructure\Service\Account\AccountService::class => ConfigAbstractFactory::class, - Infrastructure\Service\Authentication\AuthenticationService::class => InvokableFactory::class, - Infrastructure\Service\ClientIdentification\ClientIdentificationService::class => InvokableFactory::class, - EmailService::class => EmailServiceFactory::class, - Infrastructure\Service\Token\AccessTokenService::class => Infrastructure\Service\Token\AccessTokenServiceFactory::class, - Infrastructure\Service\Token\ActivationTokenService::class => Infrastructure\Service\Token\ActivationTokenServiceFactory::class, - Infrastructure\Service\Token\PasswordTokenService::class => Infrastructure\Service\Token\PasswordTokenServiceFactory::class, - Infrastructure\Service\Token\RefreshTokenService::class => Infrastructure\Service\Token\RefreshTokenServiceFactory::class, - Infrastructure\Persistence\Table\Account\AccountAccessAuthTable::class => ConfigAbstractFactory::class, - Infrastructure\Persistence\Table\Account\AccountActivationTable::class => ConfigAbstractFactory::class, - Infrastructure\Persistence\Table\Account\AccountTable::class => ConfigAbstractFactory::class, - Infrastructure\Persistence\Table\Token\TokenTable::class => ConfigAbstractFactory::class, - - EmailInput::class => InvokableFactory::class, - PasswordInput::class => InvokableFactory::class, - AccountNameInput::class => InvokableFactory::class, - Infrastructure\Validator\AccountActivationValidator::class => ConfigAbstractFactory::class, - Infrastructure\Validator\AuthenticationValidator::class => ConfigAbstractFactory::class, - EMailValidator::class => ConfigAbstractFactory::class, - Infrastructure\Validator\PasswordValidator::class => ConfigAbstractFactory::class, - AuthenticationHandler::class => ConfigAbstractFactory::class, - AccessTokenHandler::class => ConfigAbstractFactory::class, - AccountAuthenticationService::class => ConfigAbstractFactory::class, - AccountRegisterHandler::class => ConfigAbstractFactory::class, - AccountRegisterService::class => ConfigAbstractFactory::class, - Handler\AccountActivationHandler::class => ConfigAbstractFactory::class, - AccountCreatorService::class => ConfigAbstractFactory::class, - AccountPasswordForgottenHandler::class => ConfigAbstractFactory::class, - PasswordService::class => ConfigAbstractFactory::class, - AccountPasswordHandler::class => ConfigAbstractFactory::class, - LogoutHandler::class => ConfigAbstractFactory::class, - ], - - ]; - } - - public function getAbstractFactoryConfig(): array - { - return [ - Infrastructure\Hydrator\Account\AccountActivationHydrator::class => [ - UuidFactoryInterface::class, - ], - Infrastructure\Hydrator\Account\AccountHydrator::class => [ - UuidFactoryInterface::class, - ], - Infrastructure\Hydrator\Token\TokenHydrator::class => [ - UuidFactoryInterface::class, - ], - Middleware\Account\Authentication\AuthenticationValidationMiddleware::class => [ - AuthenticationValidator::class, - ], - Middleware\Account\Validation\ActivationInputValidatorMiddleware::class => [ - AccountActivationValidator::class, - ], - Middleware\Account\Validation\EmailInputValidatorMiddleware::class => [ - EMailValidator::class, - ], - Middleware\Account\Validation\PasswordInputValidatorMiddleware::class => [ - PasswordValidator::class, - ], - Middleware\Account\LastActivityUpdaterMiddleware::class => [ - AccountRepositoryInterface::class, - ], - Infrastructure\Service\Account\PasswordChangeService::class => [ - AccountRepositoryInterface::class, - TokenRepositoryInterface::class, - AccountService::class, - ], - Middleware\Account\RequestAuthenticationMiddleware::class => [ - AccessTokenService::class, - AccountRepositoryInterface::class, - UuidFactoryInterface::class, - LoggerInterface::class, - ], - Middleware\ClientIdentification\ClientIdentificationMiddleware::class => [ - ClientIdentificationService::class, - ], - Middleware\Token\AccessTokenValidationMiddleware::class => [ - AccessTokenService::class, - ], - Middleware\Token\RefreshTokenAccountMiddleware::class => [ - AccountRepositoryInterface::class, - ], - Middleware\Token\RefreshTokenDatabaseExistenceMiddleware::class => [ - AccountAccessAuthRepositoryInterface::class, - ], - Middleware\Token\RefreshTokenValidationMiddleware::class => [ - RefreshTokenService::class, - ], - Middleware\Token\RefreshTokenViaBodyValidationMiddleware::class => [ - RefreshTokenService::class, - ], - Infrastructure\Persistence\Repository\Account\AccountAccessAuthRepository::class => [ - AccountAccessAuthStoreInterface::class, - ], - Infrastructure\Persistence\Repository\Account\AccountActivationRepository::class => [ - AccountActivationStoreInterface::class, - ], - Infrastructure\Persistence\Repository\Account\AccountRepository::class => [ - AccountStoreInterface::class, - ], - Infrastructure\Persistence\Repository\Token\TokenRepository::class => [ - TokenStoreInterface::class, - ], - Infrastructure\Service\Account\AccountService::class => [ - AccountRepositoryInterface::class, - AccountAccessAuthRepositoryInterface::class, - TokenRepositoryInterface::class, - PasswordTokenService::class, - UuidFactoryInterface::class, - ], - Infrastructure\Persistence\Table\Account\AccountAccessAuthTable::class => [ - Query::class, - AccountAccessAuthHydratorInterface::class, - ], - Infrastructure\Persistence\Table\Account\AccountActivationTable::class => [ - Query::class, - AccountActivationHydratorInterface::class, - ], - Infrastructure\Persistence\Table\Account\AccountTable::class => [ - Query::class, - AccountHydratorInterface::class, - ], - Infrastructure\Persistence\Table\Token\TokenTable::class => [ - Query::class, - TokenHydratorInterface::class, - ], - Infrastructure\Validator\AccountActivationValidator::class => [ - AccountNameInput::class, - PasswordInput::class, - ], - Infrastructure\Validator\AuthenticationValidator::class => [ - EmailInput::class, - PasswordInput::class, - ], - EMailValidator::class => [ - EmailInput::class, - ], - Infrastructure\Validator\PasswordValidator::class => [ - PasswordInput::class, - ], - AuthenticationHandler::class => [ - AccountAuthenticationService::class, - ], - AccessTokenHandler::class => [ - RefreshTokenService::class, - ], - AccountAuthenticationService::class => [ - AccountRepositoryInterface::class, - AccountAccessAuthRepositoryInterface::class, - AuthenticationService::class, - RefreshTokenService::class, - AccessTokenService::class, - AccountService::class, - ], - AccountRegisterHandler::class => [ - AccountRegisterService::class, - ], - AccountRegisterService::class => [ - AccountService::class, - AccountActivationRepositoryInterface::class, - ActivationTokenService::class, - UuidFactoryInterface::class, - ], - Handler\AccountActivationHandler::class => [ - AccountCreatorService::class, - UrlHelper::class, - ], - AccountCreatorService::class => [ - AccountActivationRepositoryInterface::class, - AccountRepositoryInterface::class, - UuidFactoryInterface::class, - ], - AccountPasswordForgottenHandler::class => [ - PasswordService::class, - ], - PasswordService::class => [ - AccountService::class, - ], - AccountPasswordHandler::class => [ - PasswordChangeService::class, - ], - LogoutHandler::class => [ - AccountService::class, - ], - ]; - } -} diff --git a/src/App/Account/Identity/src/DTO/Account/Account.php b/src/App/Account/Identity/src/DTO/Account/Account.php deleted file mode 100644 index 148e3154..00000000 --- a/src/App/Account/Identity/src/DTO/Account/Account.php +++ /dev/null @@ -1,60 +0,0 @@ -value, - format: DateTimeFormat::DEFAULT->value, - example: '2024-01-20 14:30:00' - )] - public string $registeredAt, - #[OA\Property( - description: 'The timestamp of the last activity on this account', - type: DataType::STRING->value, - format: DateTimeFormat::DEFAULT->value, - example: '2024-05-15 10:00:00' - )] - public string $lastActionAt, - ) { - } - - public static function createFromAccount(AccountInterface $account): self - { - return new self( - uuid: $account->uuid->toString(), - name: $account->name, - email: $account->email->toString(), - registeredAt: $account->registeredAt->format(DateTimeFormat::DEFAULT->value), - lastActionAt: $account->lastActionAt->format(DateTimeFormat::DEFAULT->value), - ); - } -} diff --git a/src/App/Account/Identity/src/DTO/Account/AccountPassword.php b/src/App/Account/Identity/src/DTO/Account/AccountPassword.php deleted file mode 100644 index 34473f0e..00000000 --- a/src/App/Account/Identity/src/DTO/Account/AccountPassword.php +++ /dev/null @@ -1,24 +0,0 @@ -value, - )] - public string $password, - ) { - } - - public static function fromString(string $password): self - { - return new self($password); - } -} diff --git a/src/App/Account/Identity/src/DTO/Account/AccountRegistration.php b/src/App/Account/Identity/src/DTO/Account/AccountRegistration.php deleted file mode 100644 index d46d6e1f..00000000 --- a/src/App/Account/Identity/src/DTO/Account/AccountRegistration.php +++ /dev/null @@ -1,29 +0,0 @@ -value, - )] - public string $accountName, - #[OA\Property( - description: 'The Password', - type: DataType::STRING->value, - )] - public string $password, - ) { - } - - public static function fromString(string $accountName, string $password): self - { - return new self($accountName, $password); - } -} diff --git a/src/App/Account/Identity/src/DTO/Account/ApiMe.php b/src/App/Account/Identity/src/DTO/Account/ApiMe.php deleted file mode 100644 index f7b42b05..00000000 --- a/src/App/Account/Identity/src/DTO/Account/ApiMe.php +++ /dev/null @@ -1,16 +0,0 @@ -value, - )] - public string $email, - #[OA\Property( - description: 'The Password from Account', - type: DataType::STRING->value, - )] - public string $password, - ) { - } - - public static function fromArray(array $data): self - { - return new self( - $data['email'] ?? '', - $data['password'] ?? '', - ); - } -} diff --git a/src/App/Account/Identity/src/DTO/Client/ClientIdentification.php b/src/App/Account/Identity/src/DTO/Client/ClientIdentification.php deleted file mode 100644 index 2c4d8d75..00000000 --- a/src/App/Account/Identity/src/DTO/Client/ClientIdentification.php +++ /dev/null @@ -1,17 +0,0 @@ -value, - )] - public string $email, - ) { - } - - public static function fromString(string $email): self - { - return new self($email); - } -} diff --git a/src/App/Account/Identity/src/DTO/Response/AuthenticationResponse.php b/src/App/Account/Identity/src/DTO/Response/AuthenticationResponse.php deleted file mode 100644 index c9a56862..00000000 --- a/src/App/Account/Identity/src/DTO/Response/AuthenticationResponse.php +++ /dev/null @@ -1,31 +0,0 @@ -value, - )] - public string $accessToken, - #[OA\Property( - description: 'The refresh token after a valid log-in', - type: DataType::STRING->value, - )] - public string $refreshToken, - ) { - } - - public static function from(AccessToken $accessToken, RefreshToken $refreshToken): self - { - return new self($accessToken->accessToken, $refreshToken->refreshToken); - } -} diff --git a/src/App/Account/Identity/src/DTO/Response/HttpResponseMessage.php b/src/App/Account/Identity/src/DTO/Response/HttpResponseMessage.php deleted file mode 100644 index e87df571..00000000 --- a/src/App/Account/Identity/src/DTO/Response/HttpResponseMessage.php +++ /dev/null @@ -1,33 +0,0 @@ -value, - example: HTTP::STATUS_BAD_REQUEST - )] - public int $statusCode, - #[OA\Property( - description: 'The Message', - type: DataType::STRING->value, - example: IdentityStatusMessage::BAD_REQUEST - )] - public string $message, - ) { - } - - public static function create(int $statusCode, string $message): self - { - return new self($statusCode, $message); - } -} diff --git a/src/App/Account/Identity/src/DTO/Token/AccessToken.php b/src/App/Account/Identity/src/DTO/Token/AccessToken.php deleted file mode 100644 index b8b6a66a..00000000 --- a/src/App/Account/Identity/src/DTO/Token/AccessToken.php +++ /dev/null @@ -1,24 +0,0 @@ -value, - )] - public string $accessToken, - ) { - } - - public static function fromString(string $token): self - { - return new self($token); - } -} diff --git a/src/App/Account/Identity/src/DTO/Token/AccountPasswordToken.php b/src/App/Account/Identity/src/DTO/Token/AccountPasswordToken.php deleted file mode 100644 index 9f475c65..00000000 --- a/src/App/Account/Identity/src/DTO/Token/AccountPasswordToken.php +++ /dev/null @@ -1,24 +0,0 @@ -value, - )] - public string $accountPasswordToken, - ) { - } - - public static function fromString(string $accountPasswordToken): self - { - return new self($accountPasswordToken); - } -} diff --git a/src/App/Account/Identity/src/DTO/Token/JwtTokenConfig.php b/src/App/Account/Identity/src/DTO/Token/JwtTokenConfig.php deleted file mode 100644 index 0450635e..00000000 --- a/src/App/Account/Identity/src/DTO/Token/JwtTokenConfig.php +++ /dev/null @@ -1,26 +0,0 @@ -value, - )] - public string $refreshToken, - ) { - } - - public static function fromString(string $token): self - { - return new self($token); - } -} diff --git a/src/App/Account/Identity/src/DTO/Token/Token.php b/src/App/Account/Identity/src/DTO/Token/Token.php deleted file mode 100644 index 1270fb90..00000000 --- a/src/App/Account/Identity/src/DTO/Token/Token.php +++ /dev/null @@ -1,24 +0,0 @@ -value, - )] - public ?string $token, - ) { - } - - public static function fromString(?string $token): self - { - return new self($token); - } -} diff --git a/src/App/Account/Identity/src/Domain/Account.php b/src/App/Account/Identity/src/Domain/Account.php deleted file mode 100644 index d846ca47..00000000 --- a/src/App/Account/Identity/src/Domain/Account.php +++ /dev/null @@ -1,26 +0,0 @@ -account, $this->accountId); - } -} diff --git a/src/App/Account/Identity/src/Domain/Exception/DuplicateEMailException.php b/src/App/Account/Identity/src/Domain/Exception/DuplicateEMailException.php deleted file mode 100644 index 5cb84f00..00000000 --- a/src/App/Account/Identity/src/Domain/Exception/DuplicateEMailException.php +++ /dev/null @@ -1,14 +0,0 @@ - []]], - tags: ['Account'] - )] - #[OA\Response( - response: HTTP::STATUS_OK, - description: 'Successfully issued a new access token.', - content: [new OA\JsonContent(ref: AccessToken::class)] - )] - #[OA\Response( - response: HTTP::STATUS_UNAUTHORIZED, - description: 'Authentication failed. This happens if the refresh token is expired, ' . - 'revoked, or invalid. The user must perform a full login again.', - content: [new OA\JsonContent(ref: HttpResponseMessage::class)] - )] - public function handle(ServerRequestInterface $request): ResponseInterface - { - $refreshToken = $request->getAttribute(RefreshToken::class); - $clientIdentification = $request->getAttribute(ClientIdentification::class); - - $refreshedAccessToken = $this->refreshTokenService->refresh($refreshToken, $clientIdentification); - - return new JsonResponse($refreshedAccessToken, HTTP::STATUS_OK); - } -} diff --git a/src/App/Account/Identity/src/Handler/AccountActivationHandler.php b/src/App/Account/Identity/src/Handler/AccountActivationHandler.php deleted file mode 100644 index b27d8871..00000000 --- a/src/App/Account/Identity/src/Handler/AccountActivationHandler.php +++ /dev/null @@ -1,70 +0,0 @@ -getAttribute('token'); - $accountData = $request->getAttribute(AccountRegistration::class); - - $account = $this->accountCreator->create($accountData, $activationToken); - - $location = $this->urlHelper->generate('api_account_detail', ['accountUuid' => $account->uuid]); - - return new JsonResponse($account, HTTP::STATUS_CREATED, ['Location' => $location]); - } -} diff --git a/src/App/Account/Identity/src/Handler/AccountPasswordForgottenHandler.php b/src/App/Account/Identity/src/Handler/AccountPasswordForgottenHandler.php deleted file mode 100644 index 7355e58f..00000000 --- a/src/App/Account/Identity/src/Handler/AccountPasswordForgottenHandler.php +++ /dev/null @@ -1,48 +0,0 @@ -getAttribute(EmailType::class); - $this->passwordService->sendTokenForInitiateResetPassword($email); - - return new JsonResponse([], HTTP::STATUS_OK); - } -} diff --git a/src/App/Account/Identity/src/Handler/AccountPasswordHandler.php b/src/App/Account/Identity/src/Handler/AccountPasswordHandler.php deleted file mode 100644 index f4fe1d0a..00000000 --- a/src/App/Account/Identity/src/Handler/AccountPasswordHandler.php +++ /dev/null @@ -1,66 +0,0 @@ -getAttribute('token')); - $password = $request->getAttribute(AccountPassword::class); - - $this->passwordChangeService->change($token, $password); - - return new JsonResponse([], HTTP::STATUS_OK); - } -} diff --git a/src/App/Account/Identity/src/Handler/AccountRegisterHandler.php b/src/App/Account/Identity/src/Handler/AccountRegisterHandler.php deleted file mode 100644 index f74baec8..00000000 --- a/src/App/Account/Identity/src/Handler/AccountRegisterHandler.php +++ /dev/null @@ -1,50 +0,0 @@ -getAttribute(EmailType::class); - - $this->accountRegisterService->register($email); - - - return new JsonResponse([], HTTP::STATUS_OK); - } -} diff --git a/src/App/Account/Identity/src/Handler/AuthenticationHandler.php b/src/App/Account/Identity/src/Handler/AuthenticationHandler.php deleted file mode 100644 index f2873239..00000000 --- a/src/App/Account/Identity/src/Handler/AuthenticationHandler.php +++ /dev/null @@ -1,63 +0,0 @@ -getAttribute(AuthenticationRequest::class); - $clientId = $request->getAttribute(ClientIdentification::class); - - $response = $this->authService->authenticate($data, $clientId); - - return new JsonResponse($response, HTTP::STATUS_OK); - } -} diff --git a/src/App/Account/Identity/src/Handler/LogoutHandler.php b/src/App/Account/Identity/src/Handler/LogoutHandler.php deleted file mode 100644 index 473718a9..00000000 --- a/src/App/Account/Identity/src/Handler/LogoutHandler.php +++ /dev/null @@ -1,75 +0,0 @@ - []]], - tags: ['Account'] - )] - #[OA\RequestBody( - description: 'The refresh token that should be invalidated.', - required: true, - content: new OA\JsonContent( - properties: [ - new OA\Property( - property: 'refreshToken', - description: 'The full refresh token string', - type: 'string', - example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' - ), - ], - type: 'object' - ) - )] - #[OA\Response( - response: HTTP::STATUS_NO_CONTENT, - description: 'Logout successful. The refresh token has been deleted and the session is invalidated.', - content: [new OA\JsonContent(ref: HttpResponseMessage::class)] - )] - #[OA\Response( - response: HTTP::STATUS_BAD_REQUEST, - description: 'Bad Request. The refresh token is missing in the body or is malformed.', - content: [new OA\JsonContent(ref: HttpResponseMessage::class)] - )] - #[OA\Response( - response: HTTP::STATUS_UNAUTHORIZED, - description: 'Unauthorized. The access token is missing, expired, or the user could not be identified.', - content: [new OA\JsonContent(ref: HttpResponseMessage::class)] - )] - public function handle(ServerRequestInterface $request): ResponseInterface - { - $account = $request->getAttribute(AccountInterface::AUTHENTICATED); - $refreshToken = $request->getAttribute(RefreshToken::class); - - $this->accountService->logout($account, $refreshToken); - - $response = HttpResponseMessage::create(HTTP::STATUS_NO_CONTENT, IdentityStatusMessage::SUCCESS); - - return new JsonResponse($response, $response->statusCode); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Hydrator/Account/AccountAccessAuthHydrator.php b/src/App/Account/Identity/src/Infrastructure/Hydrator/Account/AccountAccessAuthHydrator.php deleted file mode 100644 index 4469bb98..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Hydrator/Account/AccountAccessAuthHydrator.php +++ /dev/null @@ -1,69 +0,0 @@ -hydrate($entity); - } - - return $collection; - } - - public function extract(AccountAccessAuthInterface $object): array - { - return [ - 'id' => $object->id, - 'accountId' => $object->accountId, - 'label' => $object->label, - 'refreshToken' => $object->refreshToken, - 'userAgent' => $object->userAgent, - 'clientIdentHash' => $object->clientIdentHash, - 'createdAt' => $object->createdAt->format(DateTimeFormat::DEFAULT->value), - ]; - } - - public function extractCollection(AccountAccessAuthCollectionInterface $collection): array - { - $data = []; - - foreach ($collection as $entity) { - $data[] = $this->extract($entity); - } - - return $data; - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Hydrator/Account/AccountActivationHydrator.php b/src/App/Account/Identity/src/Infrastructure/Hydrator/Account/AccountActivationHydrator.php deleted file mode 100644 index a6452fba..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Hydrator/Account/AccountActivationHydrator.php +++ /dev/null @@ -1,63 +0,0 @@ -uuid->fromString($data['token']), - createdAt: new DateTimeImmutable($data['createdAt']), - ); - } - - public function hydrateCollection(array $data): AccountActivationCollectionInterface - { - $collection = new AccountActivationCollection(); - - foreach ($data as $entity) { - $collection[] = $this->hydrate($entity); - } - - return $collection; - } - - public function extract(AccountActivationInterface $object): array - { - return [ - 'id' => $object->id, - 'email' => $object->email->toString(), - 'token' => $object->token->toString(), - 'createdAt' => $object->createdAt->format(DateTimeFormat::DEFAULT->value), - ]; - } - - public function extractCollection(AccountActivationCollectionInterface $collection): array - { - $data = []; - - foreach ($collection as $entity) { - $data[] = $this->extract($entity); - } - - return $data; - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Hydrator/Account/AccountHydrator.php b/src/App/Account/Identity/src/Infrastructure/Hydrator/Account/AccountHydrator.php deleted file mode 100644 index f8130288..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Hydrator/Account/AccountHydrator.php +++ /dev/null @@ -1,76 +0,0 @@ -uuid->fromString($data['uuid']), - name: $data['name'], - password: $data['password'], - email: new EmailType($data['email']), - registeredAt: new DateTimeImmutable($data['registeredAt']), - lastActionAt: new DateTimeImmutable($data['lastActionAt']), - ); - } - - /** - * @throws Exception - */ - public function hydrateCollection(array $data): AccountCollectionInterface - { - $collection = new AccountCollection(); - - foreach ($data as $entity) { - $collection[] = $this->hydrate($entity); - } - - return $collection; - } - - public function extract(AccountInterface $object): array - { - return [ - 'id' => $object->id, - 'uuid' => $object->uuid->toString(), - 'name' => $object->name, - 'password' => $object->password, - 'email' => $object->email->toString(), - 'registeredAt' => $object->registeredAt->format(DateTimeFormat::DEFAULT->value), - 'lastActionAt' => $object->lastActionAt->format(DateTimeFormat::DEFAULT->value), - ]; - } - - public function extractCollection(AccountCollectionInterface $collection): array - { - $data = []; - - foreach ($collection as $entity) { - $data[] = $this->extract($entity); - } - - return $data; - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Hydrator/Token/TokenHydrator.php b/src/App/Account/Identity/src/Infrastructure/Hydrator/Token/TokenHydrator.php deleted file mode 100644 index 233b3057..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Hydrator/Token/TokenHydrator.php +++ /dev/null @@ -1,65 +0,0 @@ -uuid->fromString($data['token']), - createdAt: new DateTimeImmutable($data['createdAt']), - ); - } - - public function hydrateCollection(array $data): TokenCollectionInterface - { - $collection = new TokenCollection(); - - foreach ($data as $entity) { - $collection[] = $this->hydrate($entity); - } - - return $collection; - } - - public function extract(TokenInterface $object): array - { - return [ - 'id' => $object->id, - 'accountId' => $object->accountId, - 'tokenType' => $object->tokenType->value, - 'token' => $object->token->toString(), - 'createdAt' => $object->createdAt->format(DateTimeFormat::DEFAULT->value), - ]; - } - - public function extractCollection(TokenCollectionInterface $collection): array - { - $data = []; - - foreach ($collection as $entity) { - $data[] = $this->extract($entity); - } - - return $data; - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Persistence/Repository/Account/AccountAccessAuthRepository.php b/src/App/Account/Identity/src/Infrastructure/Persistence/Repository/Account/AccountAccessAuthRepository.php deleted file mode 100644 index 53959e66..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Persistence/Repository/Account/AccountAccessAuthRepository.php +++ /dev/null @@ -1,71 +0,0 @@ -store->insert($accountAccessAuth); - } - - public function update(AccountAccessAuthInterface $accountAccessAuth): true - { - return $this->store->update($accountAccessAuth); - } - - public function deleteById(int $id): true - { - return $this->store->deleteById($id); - } - - public function findById(int $id): ?AccountAccessAuthInterface - { - return $this->store->findById($id); - } - - public function findByAccountId(int $accountId): AccountAccessAuthCollectionInterface - { - return $this->store->findByAccountId($accountId); - } - - public function findByAccountIdAndClientIdHash(int $accountId, string $clientHash): ?AccountAccessAuthInterface - { - return $this->store->findByAccountIdAndClientIdHash($accountId, $clientHash); - } - - public function findByLabel(string $label): AccountAccessAuthCollectionInterface - { - return $this->store->findByLabel($label); - } - - public function findByRefreshToken(string $refreshToken): ?AccountAccessAuthInterface - { - return $this->store->findByRefreshToken($refreshToken); - } - - public function findByUserAgent(string $userAgent): AccountAccessAuthCollectionInterface - { - return $this->store->findByUserAgent($userAgent); - } - - public function findByClientIdentHash(string $clientIdentHash): ?AccountAccessAuthInterface - { - return $this->store->findByClientIdentHash($clientIdentHash); - } - - public function findAll(): AccountAccessAuthCollectionInterface - { - return $this->store->findAll(); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Persistence/Repository/Account/AccountActivationRepository.php b/src/App/Account/Identity/src/Infrastructure/Persistence/Repository/Account/AccountActivationRepository.php deleted file mode 100644 index bf80c981..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Persistence/Repository/Account/AccountActivationRepository.php +++ /dev/null @@ -1,57 +0,0 @@ -store->insert($data); - } - - public function update(AccountActivationInterface $data): true - { - return $this->store->update($data); - } - - public function findById(int $id): ?AccountActivationInterface - { - return $this->store->findById($id); - } - - public function findEmail(EmailType $email): AccountActivationCollectionInterface - { - return $this->store->findByEmail($email); - } - - public function findByToken(string $token): ?AccountActivationInterface - { - return $this->store->findByToken($token); - } - - public function findAll(): AccountActivationCollectionInterface - { - return $this->store->findAll(); - } - - public function deleteById(int $id): true - { - return $this->store->deleteById($id); - } - - public function deleteByEmail(EmailType $email): true - { - return $this->store->deleteByEmail($email); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Persistence/Repository/Account/AccountRepository.php b/src/App/Account/Identity/src/Infrastructure/Persistence/Repository/Account/AccountRepository.php deleted file mode 100644 index b6597cec..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Persistence/Repository/Account/AccountRepository.php +++ /dev/null @@ -1,58 +0,0 @@ -store->insert($data); - } - - public function update(AccountInterface $data): true - { - return $this->store->update($data); - } - - public function deleteById(int $id): true - { - return $this->store->deleteById($id); - } - - public function findById(int $id): ?AccountInterface - { - return $this->store->findById($id); - } - - public function findByUuid(UuidInterface $uuid): ?AccountInterface - { - return $this->store->findByUuid($uuid); - } - - public function findByName(string $name): ?AccountInterface - { - return $this->store->findByName($name); - } - - public function findByEmail(EmailType $email): ?AccountInterface - { - return $this->store->findByEmail($email); - } - - public function findAll(): AccountCollectionInterface - { - return $this->store->findAll(); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Persistence/Repository/Token/TokenRepository.php b/src/App/Account/Identity/src/Infrastructure/Persistence/Repository/Token/TokenRepository.php deleted file mode 100644 index 4e7286ed..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Persistence/Repository/Token/TokenRepository.php +++ /dev/null @@ -1,56 +0,0 @@ -store->insert($data); - } - - public function update(TokenInterface $data): true - { - return $this->store->update($data); - } - - public function findById(int $id): ?TokenInterface - { - return $this->store->findById($id); - } - - public function findByAccountId(int $accountId): TokenCollectionInterface - { - return $this->store->findByAccountId($accountId); - } - - public function findByToken(string $token): ?TokenInterface - { - return $this->store->findByToken($token); - } - - public function findAll(): TokenCollectionInterface - { - return $this->store->findAll(); - } - - public function deleteById(int $id): true - { - return $this->store->deleteById($id); - } - - public function deleteByAccountId(int $accountId): true - { - return $this->store->deleteByAccountId($accountId); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Persistence/Table/Account/AccountAccessAuthTable.php b/src/App/Account/Identity/src/Infrastructure/Persistence/Table/Account/AccountAccessAuthTable.php deleted file mode 100644 index 95af4066..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Persistence/Table/Account/AccountAccessAuthTable.php +++ /dev/null @@ -1,144 +0,0 @@ -hydrator->extract($data); - - unset($value['id']); - - try { - $lastInsertId = $this->query->insertInto($this->table, $value)->execute(); - } catch (Exception | PDOException $e) { - return throw new DuplicateEntryException($this->getTableName(), $data->id); - } - - return true; - } - - public function update(AccountAccessAuthInterface $data): true - { - $value = $this->hydrator->extract($data); - - $result = $this->query->update($this->table, $value, $data->id)->execute(); - - if ($result === false) { - throw new InvalidArgumentException( - sprintf('Unknown Error while updating %s with id: %s', $this->getTableName(), $data->id) - ); - } - - return true; - } - - public function findById(int $id): ?AccountAccessAuthInterface - { - $result = $this->query->from($this->table) - ->where('id', $id) - ->fetch(); - - return is_array($result) ? $this->hydrator->hydrate($result) : null; - } - - public function findByAccountId(int $accountId): AccountAccessAuthCollectionInterface - { - $result = $this->query->from($this->table) - ->where('userId', $accountId) - ->fetchAll(); - - return is_array($result) - ? $this->hydrator->hydrateCollection($result) - : $this->hydrator->hydrateCollection( - [] - ); - } - - public function findByAccountIdAndClientIdHash(int $accountId, string $clientHash): ?AccountAccessAuthInterface - { - $result = $this->query->from($this->table) - ->where('accountId', $accountId) - ->where('clientIdentHash', $clientHash) - ->fetch(); - - return is_array($result) ? $this->hydrator->hydrate($result) : null; - } - - public function findByLabel(string $label): AccountAccessAuthCollectionInterface - { - $result = $this->query->from($this->table) - ->where('label', $label) - ->fetchAll(); - - return is_array($result) - ? $this->hydrator->hydrateCollection($result) - : $this->hydrator->hydrateCollection( - [] - ); - } - - public function findByRefreshToken(string $refreshToken): ?AccountAccessAuthInterface - { - $result = $this->query->from($this->table) - ->where('refreshToken', $refreshToken) - ->fetch(); - - return is_array($result) ? $this->hydrator->hydrate($result) : null; - } - - public function findByUserAgent(string $userAgent): AccountAccessAuthCollectionInterface - { - $result = $this->query->from($this->table) - ->where('userAgent', $userAgent) - ->fetchAll(); - - return is_array($result) - ? $this->hydrator->hydrateCollection($result) - : $this->hydrator->hydrateCollection( - [] - ); - } - - public function findByClientIdentHash(string $clientIdentHash): ?AccountAccessAuthInterface - { - $result = $this->query->from($this->table) - ->where('clientIdentHash', $clientIdentHash) - ->fetch(); - - return is_array($result) ? $this->hydrator->hydrate($result) : null; - } - - public function findAll(): AccountAccessAuthCollectionInterface - { - $result = $this->query->from($this->table)->fetchAll(); - - return is_array($result) - ? $this->hydrator->hydrateCollection($result) - : $this->hydrator->hydrateCollection( - [] - ); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Persistence/Table/Account/AccountActivationTable.php b/src/App/Account/Identity/src/Infrastructure/Persistence/Table/Account/AccountActivationTable.php deleted file mode 100644 index 389e109e..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Persistence/Table/Account/AccountActivationTable.php +++ /dev/null @@ -1,106 +0,0 @@ -hydrator->extract($data); - - unset($value['id']); - - try { - $this->query->insertInto($this->table, $value)->execute(); - } catch (PDOException $e) { - throw new DuplicateEntryException($this->getTableName(), $data->id); - } - - return true; - } - - public function update(AccountActivationInterface $data): true - { - $value = $this->hydrator->extract($data); - - $result = $this->query->update($this->table, $value, $data->id)->execute(); - - if ($result === false) { - throw new InvalidArgumentException( - sprintf('Unknown Error while updating %s with id: %s', $this->getTableName(), $data->id) - ); - } - - return true; - } - - public function findById(int $id): ?AccountActivationInterface - { - $result = $this->query->from($this->table) - ->where('id', $id) - ->fetch(); - - return is_array($result) ? $this->hydrator->hydrate($result) : null; - } - - public function findByEmail(EmailType $email): AccountActivationCollectionInterface - { - $result = $this->query->from($this->table) - ->where('email', $email->toString()) - ->fetchAll(); - - return is_array($result) ? $this->hydrator->hydrateCollection($result) : $this->hydrator->hydrateCollection([]); - } - - public function findByToken(string $token): ?AccountActivationInterface - { - $result = $this->query->from($this->table) - ->where('token', $token) - ->fetch(); - - return is_array($result) ? $this->hydrator->hydrate($result) : null; - } - - public function findAll(): AccountActivationCollectionInterface - { - $result = $this->query->from($this->table)->fetchAll(); - - return is_array($result) ? $this->hydrator->hydrateCollection($result) : $this->hydrator->hydrateCollection([]); - } - - public function deleteByEmail(EmailType $email): true - { - $result = $this->query->delete($this->table) - ->where('email', $email->toString()) - ->execute(); - - if ($result === false) { - throw new InvalidArgumentException( - sprintf('Failed to delete %s table with email: `%s`', $this->getTableName(), $email->toString()) - ); - } - - return true; - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Persistence/Table/Account/AccountTable.php b/src/App/Account/Identity/src/Infrastructure/Persistence/Table/Account/AccountTable.php deleted file mode 100644 index 44ef29d4..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Persistence/Table/Account/AccountTable.php +++ /dev/null @@ -1,107 +0,0 @@ -hydrator->extract($data); - - unset($value['id']); - - - try { - $lastInsertId = $this->query->insertInto($this->table, $value)->execute(); - } catch (PDOException $e) { - throw new DuplicateEntryException($this->getTableName(), $data->id); - } - - return (int)$lastInsertId; - } - - public function update(AccountInterface $data): true - { - $value = $this->hydrator->extract($data); - - $result = $this->query->update($this->table, $value, $data->id)->execute(); - - if ($result === false) { - throw new InvalidArgumentException( - sprintf('Unknown Error while updating %s with id: %s', $this->getTableName(), $data->id) - ); - } - - return true; - } - - public function findById(int $id): ?AccountInterface - { - $result = $this->query->from($this->table) - ->where('id', $id) - ->fetch(); - - return is_array($result) ? $this->hydrator->hydrate($result) : null; - } - - public function findByUuid(UuidInterface $uuid): ?AccountInterface - { - $result = $this->query->from($this->table) - ->where('uuid', $uuid->toString()) - ->fetch(); - - return is_array($result) ? $this->hydrator->hydrate($result) : null; - } - - public function findByName(string $name): ?AccountInterface - { - $result = $this->query->from($this->table) - ->where('name', $name) - ->fetch(); - - return is_array($result) ? $this->hydrator->hydrate($result) : null; - } - - public function findByEmail(EmailType $email): ?AccountInterface - { - $result = $this->query->from($this->table) - ->where('email', $email->toString()) - ->fetch(); - - return is_array($result) ? $this->hydrator->hydrate($result) : null; - } - - public function findAll(): AccountCollectionInterface - { - $result = $this->query->from($this->table)->fetchAll(); - - return is_array($result) ? $this->hydrator->hydrateCollection($result) : $this->hydrator->hydrateCollection([]); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Persistence/Table/Token/TokenTable.php b/src/App/Account/Identity/src/Infrastructure/Persistence/Table/Token/TokenTable.php deleted file mode 100644 index 739e341b..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Persistence/Table/Token/TokenTable.php +++ /dev/null @@ -1,105 +0,0 @@ -hydrator->extract($data); - - unset($value['id']); - - try { - $this->query->insertInto($this->table, $value)->execute(); - } catch (PDOException $e) { - throw new DuplicateEntryException($this->getTableName(), $data->id); - } - - return true; - } - - public function update(TokenInterface $data): true - { - $value = $this->hydrator->extract($data); - - $result = $this->query->update($this->table, $value, $data->id)->execute(); - - if ($result === false) { - throw new InvalidArgumentException( - sprintf('Unknown Error while updating %s with id: %s', $this->getTableName(), $data->id) - ); - } - - return true; - } - - public function findById(int $id): ?TokenInterface - { - $result = $this->query->from($this->table) - ->where('id', $id) - ->fetch(); - - return is_array($result) ? $this->hydrator->hydrate($result) : null; - } - - public function findByAccountId(int $accountId): TokenCollectionInterface - { - $result = $this->query->from($this->table) - ->where('accountId', $accountId) - ->fetchAll(); - - return is_array($result) ? $this->hydrator->hydrateCollection($result) : $this->hydrator->hydrateCollection([]); - } - - public function findByToken(string $token): ?TokenInterface - { - $result = $this->query->from($this->table) - ->where('token', $token) - ->fetch(); - - return is_array($result) ? $this->hydrator->hydrate($result) : null; - } - - public function findAll(): TokenCollectionInterface - { - $result = $this->query->from($this->table)->fetchAll(); - - return is_array($result) ? $this->hydrator->hydrateCollection($result) : $this->hydrator->hydrateCollection([]); - } - - public function deleteByAccountId(int $accountId): true - { - $result = $this->query->delete($this->table) - ->where('accountId', $accountId) - ->execute(); - - if ($result === false) { - throw new InvalidArgumentException( - sprintf('Failed to delete %s table with accountId: `%s`', $this->getTableName(), $accountId) - ); - } - - return true; - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Service/Account/AccountAuthenticationService.php b/src/App/Account/Identity/src/Infrastructure/Service/Account/AccountAuthenticationService.php deleted file mode 100644 index 8476ef19..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Service/Account/AccountAuthenticationService.php +++ /dev/null @@ -1,78 +0,0 @@ -accountRepository->findByEmail(EmailType::fromString($auth->email)); - if (!($account instanceof AccountInterface)) { - throw new AccountNotFoundException(email: $auth->email); - } - - if (!$this->authenticationService->isPasswordMatch($auth->password, $account->password)) { - throw new PasswordMismatchException(email: $auth->email); - } - - $refreshToken = $this->refreshTokenService->generate($clientId); - $accessToken = $this->accessTokenService->generate($account->uuid); - - $accountAccessAuth = new AccountAccessAuth( - null, - $account->id, - 'default', - $refreshToken->refreshToken, - $clientId->clientIdentificationData->userAgent, - $clientId->identificationHash, - new DateTimeImmutable() - ); - - try { - $this->accountAccessAuthRepository->insert($accountAccessAuth); - } catch (DuplicateEntryException $e) { - throw new DuplicateAuthException( - account: $account->name, - accountId: $account->id, - clientId: $clientId->identificationHash, - errorMessage: $e->getMessage(), - ); - } - - $this->accountService->updateLastAction($account); - - return AuthenticationResponse::from($accessToken, $refreshToken); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Service/Account/AccountCreatorService.php b/src/App/Account/Identity/src/Infrastructure/Service/Account/AccountCreatorService.php deleted file mode 100644 index 06639321..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Service/Account/AccountCreatorService.php +++ /dev/null @@ -1,92 +0,0 @@ - $activationToken, - ] - ); - } - - $persistActivationToken = $this->accountActivationRepository->findByToken($activationToken); - - if (!$persistActivationToken instanceof AccountActivationInterface) { - throw new HttpInvalidArgumentException( - IdentityLogMessage::ACTIVATION_TOKEN_MISSING, - IdentityStatusMessage::TOKEN_INVALID, - [ - 'Invalid activation token:' => $activationToken, - ] - ); - } - - $account = new Account( - id: null, - uuid: $this->uuid->uuid7(), - name: $accountRegistration->accountName, - password: password_hash($accountRegistration->password, PASSWORD_BCRYPT), - email: $persistActivationToken->email, - registeredAt: new DateTimeImmutable(), - lastActionAt: new DateTimeImmutable() - ); - - try { - $accountId = $this->accountRepository->insert($account); - } catch (DuplicateEntryException $e) { - throw new HttpDuplicateEntryException( - IdentityLogMessage::ACCOUNT_ALREADY_EXISTS, - IdentityStatusMessage::INVALID_DATA, - [ - 'E-Mail' => $account->email->toString(), - 'Exception Message:' => $e->getMessage(), - ] - ); - } - - try { - $this->accountActivationRepository->deleteById($persistActivationToken->id); - } catch (InvalidArgumentException $exception) { - throw new HttpInvalidArgumentException( - IdentityLogMessage::ACCOUNT_UPDATE_UNKNOWN_ERROR, - IdentityStatusMessage::UNKNOWN_ERROR, - [ - 'account' => $account->name, - 'exception' => $exception, - ] - ); - } - - $account = $this->accountRepository->findById($accountId); - return AccountDTO::createFromAccount($account); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Service/Account/AccountRegisterService.php b/src/App/Account/Identity/src/Infrastructure/Service/Account/AccountRegisterService.php deleted file mode 100644 index a449a79f..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Service/Account/AccountRegisterService.php +++ /dev/null @@ -1,41 +0,0 @@ -accountService->isEmailAvailable($email)) { - $this->accountService->sendTokenForPasswordChange($email); - throw new DuplicateEmailException($email->toString()); - } - - $activation = new AccountActivation( - id: null, - email: $email, - token: $this->uuid->uuid7(), - createdAt: new DateTimeImmutable() - ); - - $this->accountActivationRepository->insert($activation); - - $this->activationTokenService->sendEmail($activation); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Service/Account/AccountRegisterServiceInterface.php b/src/App/Account/Identity/src/Infrastructure/Service/Account/AccountRegisterServiceInterface.php deleted file mode 100644 index d236f60b..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Service/Account/AccountRegisterServiceInterface.php +++ /dev/null @@ -1,10 +0,0 @@ -accountRepository->findByEmail($email); - $token = $this->createPasswordChangeTokenForUserId($account->id); - $this->tokenRepository->insert($token); - $this->tokenService->sendEmail($email, $token); - } - - public function isEmailAvailable(EmailType $email): bool - { - $account = $this->accountRepository->findByEmail($email); - - return $account === null; - } - - public function createPasswordChangeTokenForUserId(int $userId): TokenInterface - { - return new Token( - id: null, - accountId: $userId, - tokenType: TokenType::EMail, - token: $this->uuid->uuid7(), - createdAt: new DateTimeImmutable() - ); - } - - public function cryptPassword(string $password): string - { - return password_hash($password, PASSWORD_BCRYPT); - } - - public function updateLastAction(AccountInterface $account): void - { - $this->accountRepository->update( - $account->with(lastActionAt: new DateTimeImmutable()) - ); - } - - public function logout(AccountInterface $account, RefreshToken $refreshToken): void - { - $accountAccessAuth = $this->authRepository->findByRefreshToken($refreshToken->refreshToken); - - if (!($accountAccessAuth instanceof AccountAccessAuthInterface)) { - throw new HttpUnauthorizedException( - IdentityLogMessage::LOGOUT_REFRESH_TOKEN_MISMATCH, - IdentityStatusMessage::UNAUTHORIZED_ACCESS, - [ - 'accountId' => $account->id, - 'refreshToken' => $refreshToken->refreshToken, - ], - Level::Warning - ); - } - - if ($account->id !== $accountAccessAuth->accountId) { - throw new HttpUnauthorizedException( - IdentityLogMessage::LOGOUT_REFRESH_TOKEN_MISMATCH, - IdentityStatusMessage::UNAUTHORIZED_ACCESS, - [ - 'accountId' => $account->id, - 'refreshToken' => $refreshToken->refreshToken, - ], - Level::Warning - ); - } - - $this->authRepository->deleteById($accountAccessAuth->id); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Service/Account/PasswordChangeService.php b/src/App/Account/Identity/src/Infrastructure/Service/Account/PasswordChangeService.php deleted file mode 100644 index 7f876c29..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Service/Account/PasswordChangeService.php +++ /dev/null @@ -1,60 +0,0 @@ -token === null) { - $this->errorResponse(IdentityLogMessage::PASSWORD_CHANGE_TOKEN_MISSING, $token->token); - } - - $persistedToken = $this->tokenRepository->findByToken($token->token); - - if (!($persistedToken instanceof TokenInterface) || $persistedToken->tokenType !== TokenType::EMail) { - $this->errorResponse(IdentityLogMessage::PASSWORD_CHANGE_TOKEN_INVALID, $token->token); - } - - $account = $this->accountRepository->findById($persistedToken->accountId); - - if (!($account instanceof Account)) { - $this->errorResponse(IdentityLogMessage::PASSWORD_CHANGE_TOKEN_ACCOUNT_NOT_FOUND, $token->token); - } - - $hashedPassword = $this->accountService->cryptPassword($password->password); - $account = $account->with(password: $hashedPassword); - - $this->accountRepository->update($account); - $this->tokenRepository->deleteById($persistedToken->id); - } - - private function errorResponse(string $logMessage, ?string $token): void - { - throw new HttpInvalidArgumentException( - $logMessage, - IdentityStatusMessage::TOKEN_INVALID, - [ - 'Token:' => $token, - ] - ); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Service/Account/PasswordService.php b/src/App/Account/Identity/src/Infrastructure/Service/Account/PasswordService.php deleted file mode 100644 index 6fce71fa..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Service/Account/PasswordService.php +++ /dev/null @@ -1,33 +0,0 @@ -accountService->isEmailAvailable($email)) { - throw new HttpHandledInvalidArgumentAsSuccessException( - IdentityLogMessage::PASSWORD_REQUEST_MISSING_ACCOUNT, - IdentityStatusMessage::INVALID_DATA, - [ - 'email:' => $email->toString(), - ], - Level::Warning - ); - } - - $this->accountService->sendTokenForPasswordChange($email); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Service/Authentication/AuthenticationService.php b/src/App/Account/Identity/src/Infrastructure/Service/Authentication/AuthenticationService.php deleted file mode 100644 index 71adfa93..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Service/Authentication/AuthenticationService.php +++ /dev/null @@ -1,11 +0,0 @@ -getIdentificationHash($clientIdentificationData); - } - - private function getIdentificationHash(ClientIdentificationData $clientIdentificationData): string - { - return hash('sha512', serialize($clientIdentificationData)); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Service/Token/AccessTokenService.php b/src/App/Account/Identity/src/Infrastructure/Service/Token/AccessTokenService.php deleted file mode 100644 index e2dd2c98..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Service/Token/AccessTokenService.php +++ /dev/null @@ -1,37 +0,0 @@ - $this->config->iss, - 'aud' => $this->config->aud, - 'iat' => $now, - 'exp' => $now + $this->config->duration, - 'uuid' => $uuid->toString(), - ]; - - $token = JWT::encode($payload, $this->config->key, $this->config->algorithmus); - return AccessToken::fromString($token); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Service/Token/AccessTokenServiceFactory.php b/src/App/Account/Identity/src/Infrastructure/Service/Token/AccessTokenServiceFactory.php deleted file mode 100644 index 31d43e03..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Service/Token/AccessTokenServiceFactory.php +++ /dev/null @@ -1,17 +0,0 @@ -get('config')['jwt_token']['access']; - $jwtTokenConfig = JwtTokenConfig::createFromArray($jwtTokenConfig); - - return new AccessTokenService($jwtTokenConfig); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Service/Token/ActivationTokenService.php b/src/App/Account/Identity/src/Infrastructure/Service/Token/ActivationTokenService.php deleted file mode 100644 index 461e7c9a..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Service/Token/ActivationTokenService.php +++ /dev/null @@ -1,60 +0,0 @@ -projectUri, - $activation->token->toString() - ); - - $html = sprintf( - '

Hallo!

-

Vielen Dank für Ihr Interesse an ownHackathon.

-

Sie haben eine Registrierung mit dieser E-Mail-Adresse angefordert. - Um den Vorgang abzuschließen und Ihr Benutzerkonto zu erstellen, - bestätigen Sie bitte Ihre E-Mail-Adresse über den folgenden Link:

-

Account erstellen

-

Hinweis: Erst wenn Sie diesen Link anklicken, wird Ihr Account verbindlich angelegt. - Der Link ist nur für begrenzte Zeit gültig.

-

Falls Sie diese Anfrage nicht selbst gestellt haben, können Sie diese Nachricht einfach ignorieren. - Es wird in diesem Fall kein Konto erstellt und Ihre E-Mail-Adresse wird nicht dauerhaft bei uns gespeichert.

-

Mit freundlichen Grüßen,
- Ihr Team von ownHackathon

', - $this->projectUri, - $activation->token->toString() - ); - - $this->emailService->send($activation->email, $text, $html, 'Account Aktivierung'); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Service/Token/ActivationTokenServiceFactory.php b/src/App/Account/Identity/src/Infrastructure/Service/Token/ActivationTokenServiceFactory.php deleted file mode 100644 index 634ff721..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Service/Token/ActivationTokenServiceFactory.php +++ /dev/null @@ -1,17 +0,0 @@ -get(EmailService::class); - $projectUri = $container->get('config')['project']['uri']; - - return new ActivationTokenService($emailService, $projectUri); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Service/Token/PasswordTokenService.php b/src/App/Account/Identity/src/Infrastructure/Service/Token/PasswordTokenService.php deleted file mode 100644 index 8b16ad8e..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Service/Token/PasswordTokenService.php +++ /dev/null @@ -1,64 +0,0 @@ -projectUri, - $token->token->toString() - ); - - $html = sprintf( - '

Hallo!

-

Vielen Dank für Ihr Interesse an unserem Service.

-

Sie haben versucht, sich mit dieser E-Mail-Adresse neu zu registrieren oder wollen Ihr Passwort zurücksetzen. - Da unter dieser Adresse bereits ein aktives Konto bei uns besteht, - senden wir Ihnen hiermit einen Link, mit dem Sie Ihr Passwort zurücksetzen können, - falls Sie den Zugriff auf Ihren Account wiederherstellen möchten.

-

Klicken Sie auf den folgenden Link, um ein neues Passwort festzulegen:
- Passwort resetten

-

Falls Sie keine Registrierung oder Passwortänderung veranlasst haben, - können Sie diese Nachricht einfach ignorieren. Ihr Account bleibt weiterhin mit - Ihrem bestehenden Passwort geschützt.

-

Mit freundlichen Grüßen,
- Ihr Team von ownHackathon

', - $this->projectUri, - $token->token->toString() - ); - - $this->emailService->send($email, $text, $html, 'Passwort zurücksetzen Link'); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Service/Token/PasswordTokenServiceFactory.php b/src/App/Account/Identity/src/Infrastructure/Service/Token/PasswordTokenServiceFactory.php deleted file mode 100644 index 594cfee8..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Service/Token/PasswordTokenServiceFactory.php +++ /dev/null @@ -1,17 +0,0 @@ -get(EmailService::class); - $projectUri = $container->get('config')['project']['uri']; - - return new PasswordTokenService($emailService, $projectUri); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Service/Token/RefreshTokenService.php b/src/App/Account/Identity/src/Infrastructure/Service/Token/RefreshTokenService.php deleted file mode 100644 index 750222ab..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Service/Token/RefreshTokenService.php +++ /dev/null @@ -1,105 +0,0 @@ - $this->config->iss, - 'aud' => $this->config->aud, - 'iat' => $now, - 'exp' => $now + $this->config->duration, - 'ident' => $clientIdentification->identificationHash, - ]; - - $token = JWT::encode($payload, $this->config->key, $this->config->algorithmus); - - return RefreshToken::fromString($token); - } - - /** - * @throws InvalidRefreshTokenException - * @throws SecurityBreachException - * @throws AccountNotFoundException - */ - public function refresh( - RefreshToken $refreshToken, - ClientIdentification $client - ): AccessToken { - $accountAccessAuth = $this->validateTokenAndClient($refreshToken, $client); - - $account = $this->findAccountOrThrow($accountAccessAuth); - - return $this->accessTokenService->generate($account->uuid); - } - - /** - * @throws InvalidRefreshTokenException - * @throws SecurityBreachException - */ - private function validateTokenAndClient( - RefreshToken $refreshToken, - ClientIdentification $client - ): AccountAccessAuthInterface { - $accountAccessAuth = $this->accessAuthRepository->findByRefreshToken($refreshToken->refreshToken); - if (!$accountAccessAuth instanceof AccountAccessAuthInterface) { - throw new InvalidRefreshTokenException($refreshToken->refreshToken); - } - if ($accountAccessAuth->clientIdentHash !== $client->identificationHash) { - throw new SecurityBreachException( - expectedClientHash: $accountAccessAuth->clientIdentHash, - actualClientHash: $accountAccessAuth->userAgent, - expectedUserAgent: $client->identificationHash, - actualUserAgent: $client->clientIdentificationData->userAgent, - ); - } - - return $accountAccessAuth; - } - - /** - * @throws AccountNotFoundException - */ - private function findAccountOrThrow(AccountAccessAuthInterface $accountAccessAuth): AccountInterface - { - $account = $this->accountRepository->findById($accountAccessAuth->accountId); - if (!$account instanceof AccountInterface) { - throw new AccountNotFoundException( - accountId: $accountAccessAuth->accountId, - accessAuthId: $accountAccessAuth->id - ); - } - - return $account; - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Service/Token/RefreshTokenServiceFactory.php b/src/App/Account/Identity/src/Infrastructure/Service/Token/RefreshTokenServiceFactory.php deleted file mode 100644 index 7fe0a5c0..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Service/Token/RefreshTokenServiceFactory.php +++ /dev/null @@ -1,27 +0,0 @@ -get(AccountRepositoryInterface::class); - $accessAuthRepository = $container->get(AccountAccessAuthRepositoryInterface::class); - $accessTokenService = $container->get(AccessTokenService::class); - $jwtTokenConfig = $container->get('config')['jwt_token']['refresh']; - $jwtTokenConfig = JwtTokenConfig::createFromArray($jwtTokenConfig); - - return new RefreshTokenService( - $accountRepository, - $accessAuthRepository, - $accessTokenService, - $jwtTokenConfig - ); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Validator/AccountActivationValidator.php b/src/App/Account/Identity/src/Infrastructure/Validator/AccountActivationValidator.php deleted file mode 100644 index a000cf01..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Validator/AccountActivationValidator.php +++ /dev/null @@ -1,18 +0,0 @@ -add($this->accountNameInput); - $this->add($this->passwordInput); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Validator/AuthenticationValidator.php b/src/App/Account/Identity/src/Infrastructure/Validator/AuthenticationValidator.php deleted file mode 100644 index 9f745b39..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Validator/AuthenticationValidator.php +++ /dev/null @@ -1,18 +0,0 @@ -add($this->emailInput); - $this->add($this->passwordInput); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Validator/DateLessNow.php b/src/App/Account/Identity/src/Infrastructure/Validator/DateLessNow.php deleted file mode 100644 index 7a64b7b0..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Validator/DateLessNow.php +++ /dev/null @@ -1,37 +0,0 @@ - 'Date is in the past', - ]; - - public function isValid($value): bool - { - $dateNow = new DateTime(); - - try { - $dateValue = new DateTime($value); - } catch (Exception $exception) { - return false; - } - - if ($dateValue <= $dateNow) { - $this->error(self::VALID_DATE); - return false; - } - - $this->setValue($value); - - return true; - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Validator/Input/AccountNameInput.php b/src/App/Account/Identity/src/Infrastructure/Validator/Input/AccountNameInput.php deleted file mode 100644 index a506c81f..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Validator/Input/AccountNameInput.php +++ /dev/null @@ -1,26 +0,0 @@ -setRequired(true); - - $this->getFilterChain()->attachByName('StringTrim'); - - $this->getValidatorChain()->attachByName( - 'StringLength', - [ - 'encoding' => 'UTF-8', - 'min' => 3, - 'max' => 64, - ] - ); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Validator/Input/PasswordInput.php b/src/App/Account/Identity/src/Infrastructure/Validator/Input/PasswordInput.php deleted file mode 100644 index 13c8dc4e..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Validator/Input/PasswordInput.php +++ /dev/null @@ -1,26 +0,0 @@ -setRequired(true); - - $this->getFilterChain()->attachByName('StringTrim'); - - $this->getValidatorChain()->attachByName( - 'StringLength', - [ - 'encoding' => 'UTF-8', - 'min' => 6, - 'max' => 255, - ] - ); - } -} diff --git a/src/App/Account/Identity/src/Infrastructure/Validator/PasswordValidator.php b/src/App/Account/Identity/src/Infrastructure/Validator/PasswordValidator.php deleted file mode 100644 index c6021a6e..00000000 --- a/src/App/Account/Identity/src/Infrastructure/Validator/PasswordValidator.php +++ /dev/null @@ -1,15 +0,0 @@ -add($this->passwordInput); - } -} diff --git a/src/App/Account/Identity/src/Middleware/Account/Authentication/AuthenticationConditionsMiddleware.php b/src/App/Account/Identity/src/Middleware/Account/Authentication/AuthenticationConditionsMiddleware.php deleted file mode 100644 index 3c5a13fd..00000000 --- a/src/App/Account/Identity/src/Middleware/Account/Authentication/AuthenticationConditionsMiddleware.php +++ /dev/null @@ -1,30 +0,0 @@ -hasHeader('Authentication') || $request->hasHeader('Authorization')) { - throw new HttpUnauthorizedException( - IdentityLogMessage::LOGIN_DENIED_AUTH_HEADER_ALREADY_PRESENT, - IdentityStatusMessage::ACCOUNT_ALREADY_AUTHENTICATED, - [ - 'uri' => (string)$request->getUri(), - 'ip' => $request->getServerParams()['REMOTE_ADDR'] ?? 'unknown', - ] - ); - } - - return $handler->handle($request); - } -} diff --git a/src/App/Account/Identity/src/Middleware/Account/Authentication/AuthenticationValidationMiddleware.php b/src/App/Account/Identity/src/Middleware/Account/Authentication/AuthenticationValidationMiddleware.php deleted file mode 100644 index 87258b67..00000000 --- a/src/App/Account/Identity/src/Middleware/Account/Authentication/AuthenticationValidationMiddleware.php +++ /dev/null @@ -1,43 +0,0 @@ -getParsedBody(); - - $this->validator->setData($data); - - if (!$this->validator->isValid()) { - throw new HttpUnauthorizedException( - IdentityLogMessage::EMAIL_INVALID, - IdentityStatusMessage::INVALID_DATA, - [ - 'E-Mail:' => $data['email'] ?? null, - 'Validator-Message:' => $this->validator->getMessages(), - ] - ); - } - - $response = AuthenticationRequest::fromArray($this->validator->getValues()); - - return $handler->handle($request->withAttribute(AuthenticationRequest::class, $response)); - } -} diff --git a/src/App/Account/Identity/src/Middleware/Account/LastActivityUpdaterMiddleware.php b/src/App/Account/Identity/src/Middleware/Account/LastActivityUpdaterMiddleware.php deleted file mode 100644 index 34bde47d..00000000 --- a/src/App/Account/Identity/src/Middleware/Account/LastActivityUpdaterMiddleware.php +++ /dev/null @@ -1,48 +0,0 @@ -getAttribute(AccountInterface::AUTHENTICATED); - if (!($account instanceof AccountInterface)) { - return $handler->handle($request); - } - - try { - $this->accountRepository->update( - $account->with(lastActionAt: new DateTimeImmutable()) - ); - } catch (InvalidArgumentException $exception) { - throw new HttpInvalidArgumentException( - IdentityLogMessage::ACCOUNT_UPDATE_UNKNOWN_ERROR, - IdentityStatusMessage::UNKNOWN_ERROR, - [ - 'account' => $account->name, - 'exception' => $exception, - ] - ); - } - - return $handler->handle($request->withAttribute(AccountInterface::AUTHENTICATED, $account)); - } -} diff --git a/src/App/Account/Identity/src/Middleware/Account/RequestAuthenticationMiddleware.php b/src/App/Account/Identity/src/Middleware/Account/RequestAuthenticationMiddleware.php deleted file mode 100644 index 87297fe1..00000000 --- a/src/App/Account/Identity/src/Middleware/Account/RequestAuthenticationMiddleware.php +++ /dev/null @@ -1,76 +0,0 @@ -getHeaderLine('Authorization'); - - if (strlen($authorization) === 0) { - $this->logger->info('Guest call', [ - 'uri' => (string)$request->getUri(), - ]); - - return $handler->handle($request); - } - - if (!$this->accessTokenService->isValid($authorization)) { - throw new HttpUnauthorizedException( - IdentityLogMessage::ACCESS_TOKEN_EXPIRED, - IdentityStatusMessage::TOKEN_EXPIRED, - [ - 'uri' => (string)$request->getUri(), - 'ip' => $request->getServerParams()['REMOTE_ADDR'] ?? 'unknown', - ] - ); - } - - $authorization = $this->accessTokenService->decode($authorization); - $uuid = $this->uuid->fromString($authorization->uuid); - $account = $this->accountRepository->findByUuid($uuid); - if (!($account instanceof AccountInterface)) { - throw new HttpUnauthorizedException( - IdentityLogMessage::ACCESS_TOKEN_ACCOUNT_NOT_FOUND, - IdentityStatusMessage::TOKEN_INVALID, - [ - 'uri' => (string)$request->getUri(), - 'uuid' => $authorization->uuid, - ], - Level::Warning - ); - } - - $this->logger->info('Authenticated user call.', [ - 'Account' => $account->name, - 'uri' => (string)$request->getUri(), - ]); - - return $handler->handle($request->withAttribute(AccountInterface::AUTHENTICATED, $account)); - } -} diff --git a/src/App/Account/Identity/src/Middleware/Account/Validation/ActivationInputValidatorMiddleware.php b/src/App/Account/Identity/src/Middleware/Account/Validation/ActivationInputValidatorMiddleware.php deleted file mode 100644 index 48681059..00000000 --- a/src/App/Account/Identity/src/Middleware/Account/Validation/ActivationInputValidatorMiddleware.php +++ /dev/null @@ -1,45 +0,0 @@ -getParsedBody(); - - $this->validator->setData($data); - - if (!$this->validator->isValid()) { - throw new HttpInvalidArgumentException( - IdentityLogMessage::ACCOUNT_NAME_INVALID, - IdentityStatusMessage::INVALID_DATA, - [ - 'Account Name:' => $data['accountName'] ?? null, - 'Validator-Message:' => $this->validator->getMessages(), - ] - ); - } - - $data = $this->validator->getValues(); - - $response = AccountRegistration::fromString($data['accountName'], $data['password']); - - return $handler->handle($request->withAttribute(AccountRegistration::class, $response)); - } -} diff --git a/src/App/Account/Identity/src/Middleware/Account/Validation/EmailInputValidatorMiddleware.php b/src/App/Account/Identity/src/Middleware/Account/Validation/EmailInputValidatorMiddleware.php deleted file mode 100644 index cb7b6947..00000000 --- a/src/App/Account/Identity/src/Middleware/Account/Validation/EmailInputValidatorMiddleware.php +++ /dev/null @@ -1,58 +0,0 @@ -getParsedBody(); - - $this->mailValidator->setData($data); - - if (!$this->mailValidator->isValid()) { - throw new HttpInvalidArgumentException( - IdentityLogMessage::EMAIL_INVALID, - IdentityStatusMessage::INVALID_DATA, - [ - 'E-Mail:' => $data['email'] ?? null, - 'Validator Message:' => $this->mailValidator->getMessages(), - ] - ); - } - - try { - $email = new EmailType($this->mailValidator->getValues()['email']); - } catch (InvalidArgumentException) { - throw new HttpInvalidArgumentException( - IdentityLogMessage::EMAIL_INVALID, - IdentityStatusMessage::INVALID_DATA, - [ - 'E-Mail:' => $data['email'] ?? 'unknown', - ] - ); - } - - return $handler->handle($request->withAttribute(EmailType::class, $email)); - } -} diff --git a/src/App/Account/Identity/src/Middleware/Account/Validation/PasswordInputValidatorMiddleware.php b/src/App/Account/Identity/src/Middleware/Account/Validation/PasswordInputValidatorMiddleware.php deleted file mode 100644 index 21425ded..00000000 --- a/src/App/Account/Identity/src/Middleware/Account/Validation/PasswordInputValidatorMiddleware.php +++ /dev/null @@ -1,41 +0,0 @@ -getParsedBody(); - - $this->validator->setData($data); - - if (!$this->validator->isValid()) { - throw new HttpInvalidArgumentException( - IdentityLogMessage::PASSWORD_INVALID, - IdentityStatusMessage::INVALID_DATA, - [ - 'Validator Message:' => $this->validator->getMessages(), - ] - ); - } - - $password = AccountPassword::fromString($this->validator->getValues()['password']); - return $handler->handle($request->withAttribute(AccountPassword::class, $password)); - } -} diff --git a/src/App/Account/Identity/src/Middleware/ClientIdentification/ClientIdentificationMiddleware.php b/src/App/Account/Identity/src/Middleware/ClientIdentification/ClientIdentificationMiddleware.php deleted file mode 100644 index 83b32930..00000000 --- a/src/App/Account/Identity/src/Middleware/ClientIdentification/ClientIdentificationMiddleware.php +++ /dev/null @@ -1,31 +0,0 @@ -getHeaderLine('x-ident'); - $userAgent = $request->getHeaderLine('user-agent'); - - $clientIdentificationData = ClientIdentificationData::create($clientIdent, $userAgent); - $identificationHash = $this->clientIdentification->getClientIdentificationHash($clientIdentificationData); - $clientIdentification = ClientIdentification::create($clientIdentificationData, $identificationHash); - - return $handler->handle($request->withAttribute(ClientIdentification::class, $clientIdentification)); - } -} diff --git a/src/App/Account/Identity/src/Middleware/IdentityExceptionMappingMiddleware.php b/src/App/Account/Identity/src/Middleware/IdentityExceptionMappingMiddleware.php deleted file mode 100644 index b998ff2e..00000000 --- a/src/App/Account/Identity/src/Middleware/IdentityExceptionMappingMiddleware.php +++ /dev/null @@ -1,87 +0,0 @@ -handle($request); - } catch (InvalidRefreshTokenException $e) { - throw new HttpUnauthorizedException( - IdentityLogMessage::REFRESH_TOKEN_NOT_FOUND, - IdentityStatusMessage::TOKEN_NOT_PERSISTENT, - [ - 'Refresh Token:' => $e->refreshToken, - ], - Level::Warning - ); - } catch (SecurityBreachException $e) { - throw new HttpUnauthorizedException( - IdentityLogMessage::REFRESH_TOKEN_CLIENT_MISMATCH, - IdentityStatusMessage::CLIENT_UNEXPECTED, - [ - 'expected:' => $e->expectedClientHash, - 'expected UserAgent' => $e->expectedUserAgent, - 'current:' => $e->actualClientHash, - 'current UserAgent:' => $e->actualUserAgent, - ], - Level::Warning - ); - } catch (AccountNotFoundException $e) { - throw new HttpUnauthorizedException( - IdentityLogMessage::REFRESH_TOKEN_ACCOUNT_NOT_FOUND, - IdentityStatusMessage::TOKEN_INVALID, - [ - 'AccessAuth ID:' => $e->accessAuthId, - 'Account ID:' => $e->accountId, - 'E-Mail:' => $e->email, - ], - Level::Warning - ); - } catch (PasswordMismatchException $e) { - throw new HttpUnauthorizedException( - IdentityLogMessage::PASSWORD_INCORRECT, - IdentityStatusMessage::INVALID_DATA, - [ - 'E-Mail:' => $e->email, - ], - Level::Warning - ); - } catch (DuplicateAuthException $e) { - throw new HttpDuplicateEntryException( - IdentityLogMessage::DUPLICATE_SOURCE_LOGIN, - IdentityStatusMessage::INVALID_DATA, - [ - 'Account' => $e->account, - 'ClientID' => $e->clientId, - 'ErrorMessage' => $e->errorMessage, - ], - ); - } catch (DuplicateEmailException $e) { - throw new HttpHandledInvalidArgumentAsSuccessException( - IdentityLogMessage::ACCOUNT_ALREADY_EXISTS, - IdentityStatusMessage::SUCCESS, - ['email:' => $e->email] - ); - } - } -} diff --git a/src/App/Account/Identity/src/Middleware/Token/AccessTokenValidationMiddleware.php b/src/App/Account/Identity/src/Middleware/Token/AccessTokenValidationMiddleware.php deleted file mode 100644 index ffb86471..00000000 --- a/src/App/Account/Identity/src/Middleware/Token/AccessTokenValidationMiddleware.php +++ /dev/null @@ -1,47 +0,0 @@ -getHeaderLine('Authorization'); - - if (empty($accessToken)) { - throw new HttpUnauthorizedException( - IdentityLogMessage::ACCESS_TOKEN_MISSING, - IdentityStatusMessage::UNAUTHORIZED_ACCESS, - [], - Level::Warning - ); - } - - if (!$this->tokenService->isValid($accessToken)) { - throw new HttpUnauthorizedException( - IdentityLogMessage::ACCESS_TOKEN_EXPIRED, - IdentityStatusMessage::TOKEN_EXPIRED, - [ - 'Access Token:' => $accessToken, - ], - ); - } - - return $handler->handle($request); - } -} diff --git a/src/App/Account/Identity/src/Middleware/Token/RefreshTokenAccountMiddleware.php b/src/App/Account/Identity/src/Middleware/Token/RefreshTokenAccountMiddleware.php deleted file mode 100644 index 60010453..00000000 --- a/src/App/Account/Identity/src/Middleware/Token/RefreshTokenAccountMiddleware.php +++ /dev/null @@ -1,43 +0,0 @@ -getAttribute(AccountAccessAuthInterface::class); - $account = $this->accountRepository->findById($accountAccessAuth->accountId); - - if (!$account instanceof AccountAccessAuthInterface) { - throw new HttpUnauthorizedException( - IdentityLogMessage::REFRESH_TOKEN_ACCOUNT_NOT_FOUND, - IdentityStatusMessage::TOKEN_INVALID, - [ - 'AccessAuth ID:' => $accountAccessAuth->id, - 'Account ID:' => $accountAccessAuth->accountId, - ], - Level::Warning - ); - } - - return $handler->handle($request->withAttribute(AccountInterface::AUTHENTICATED, $account)); - } -} diff --git a/src/App/Account/Identity/src/Middleware/Token/RefreshTokenDatabaseExistenceMiddleware.php b/src/App/Account/Identity/src/Middleware/Token/RefreshTokenDatabaseExistenceMiddleware.php deleted file mode 100644 index e7fcf384..00000000 --- a/src/App/Account/Identity/src/Middleware/Token/RefreshTokenDatabaseExistenceMiddleware.php +++ /dev/null @@ -1,43 +0,0 @@ -getAttribute(RefreshToken::class); - - $persistToken = $this->accessAuthRepository->findByRefreshToken($refreshToken->refreshToken); - if (!($persistToken instanceof AccountAccessAuthInterface)) { - throw new HttpUnauthorizedException( - IdentityLogMessage::REFRESH_TOKEN_NOT_FOUND, - IdentityStatusMessage::TOKEN_NOT_PERSISTENT, - [ - 'Refresh Token:' => $refreshToken, - ], - Level::Warning - ); - } - - return $handler->handle($request->withAttribute(AccountAccessAuthInterface::class, $persistToken)); - } -} diff --git a/src/App/Account/Identity/src/Middleware/Token/RefreshTokenMatchClientIdentificationMiddleware.php b/src/App/Account/Identity/src/Middleware/Token/RefreshTokenMatchClientIdentificationMiddleware.php deleted file mode 100644 index 11d2ee67..00000000 --- a/src/App/Account/Identity/src/Middleware/Token/RefreshTokenMatchClientIdentificationMiddleware.php +++ /dev/null @@ -1,43 +0,0 @@ -getAttribute(AccountAccessAuthInterface::class); - - /** @var ClientIdentification $clientIdentification */ - $clientIdentification = $request->getAttribute(ClientIdentification::class); - - if ($accountAccessAuth->clientIdentHash !== $clientIdentification->identificationHash) { - throw new HttpUnauthorizedException( - IdentityLogMessage::REFRESH_TOKEN_CLIENT_MISMATCH, - IdentityStatusMessage::CLIENT_UNEXPECTED, - [ - 'expected:' => $accountAccessAuth->clientIdentHash, - 'expected UserAgent' => $accountAccessAuth->userAgent, - 'current:' => $clientIdentification->identificationHash, - 'current UserAgent:' => $clientIdentification->clientIdentificationData->userAgent, - ], - Level::Warning - ); - } - - return $handler->handle($request); - } -} diff --git a/src/App/Account/Identity/src/Middleware/Token/RefreshTokenValidationMiddleware.php b/src/App/Account/Identity/src/Middleware/Token/RefreshTokenValidationMiddleware.php deleted file mode 100644 index e397df3c..00000000 --- a/src/App/Account/Identity/src/Middleware/Token/RefreshTokenValidationMiddleware.php +++ /dev/null @@ -1,40 +0,0 @@ -getHeaderLine('Authentication'); - - if (!$this->tokenService->isValid($refreshToken)) { - throw new HttpUnauthorizedException( - IdentityLogMessage::REFRESH_TOKEN_INVALID, - IdentityStatusMessage::TOKEN_INVALID, - [ - 'Refresh Token:' => $refreshToken, - ], - ); - } - - $refreshToken = RefreshToken::fromString($refreshToken); - - return $handler->handle($request->withAttribute(RefreshToken::class, $refreshToken)); - } -} diff --git a/src/App/Account/Identity/src/Middleware/Token/RefreshTokenViaBodyValidationMiddleware.php b/src/App/Account/Identity/src/Middleware/Token/RefreshTokenViaBodyValidationMiddleware.php deleted file mode 100644 index 30e97763..00000000 --- a/src/App/Account/Identity/src/Middleware/Token/RefreshTokenViaBodyValidationMiddleware.php +++ /dev/null @@ -1,41 +0,0 @@ -getParsedBody(); - $refreshToken = $refreshToken['refreshToken'] ?? null; - - if (!$refreshToken || !$this->tokenService->isValid($refreshToken)) { - throw new HttpUnauthorizedException( - IdentityLogMessage::REFRESH_TOKEN_INVALID, - IdentityStatusMessage::TOKEN_INVALID, - [ - 'Refresh Token:' => $refreshToken, - ], - ); - } - - $refreshToken = RefreshToken::fromString($refreshToken); - - return $handler->handle($request->withAttribute(RefreshToken::class, $refreshToken)); - } -} diff --git a/src/App/Account/Profile/.gitkeep b/src/App/Account/Profile/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/src/App/ConfigProvider.php b/src/App/ConfigProvider.php index 531c178f..b4b6f206 100644 --- a/src/App/ConfigProvider.php +++ b/src/App/ConfigProvider.php @@ -9,8 +9,6 @@ class ConfigProvider public function __invoke(): array { $aggregator = new ConfigAggregator([ - \ownHackathon\Account\ConfigProvider::class, - \Exdrals\Mailing\ConfigProvider::class, \ownHackathon\Workspace\ConfigProvider::class, ]); diff --git a/src/App/Mailing/config/autoload/mail.global.dist b/src/App/Mailing/config/autoload/mail.global.dist deleted file mode 100644 index 0bb7df74..00000000 --- a/src/App/Mailing/config/autoload/mail.global.dist +++ /dev/null @@ -1,8 +0,0 @@ - [ - 'dsn' => 'smtp://mailhog:1025', - 'from' => 'example@example.com', - ], -]; diff --git a/src/App/Mailing/src/ConfigProvider.php b/src/App/Mailing/src/ConfigProvider.php deleted file mode 100644 index 13b09081..00000000 --- a/src/App/Mailing/src/ConfigProvider.php +++ /dev/null @@ -1,41 +0,0 @@ - $this->getDependencies(), - ConfigAbstractFactory::class => $this->getAbstractFactoryConfig(), - ]; - } - - public function getDependencies(): array - { - return [ - 'invokables' => [ - EmailInput::class => EmailInput::class, - PasswordInput::class => PasswordInput::class, - ], - 'aliases' => [ - \Symfony\Component\Mailer\MailerInterface::class => 'mailer', - - ], - 'factories' => [ - 'mailer' => MailFactory::class, - ], - ]; - } - - public function getAbstractFactoryConfig(): array - { - return []; - } -} diff --git a/src/App/Mailing/src/Domain/EmailType.php b/src/App/Mailing/src/Domain/EmailType.php deleted file mode 100644 index 0381d527..00000000 --- a/src/App/Mailing/src/Domain/EmailType.php +++ /dev/null @@ -1,74 +0,0 @@ -value = $value instanceof self ? (string)$value : $this->prepareValue($value); - } - - public function toString(): string - { - return $this->value; - } - - public function __toString(): string - { - return $this->toString(); - } - - public function serialize(): string - { - return $this->toString(); - } - - public function __serialize(): array - { - return ['string' => $this->toString()]; - } - - public function unserialize(string $data): void - { - $this->__construct($data); - } - - public function __unserialize(array $data): void - { - // @codeCoverageIgnoreStart - if (!isset($data['string'])) { - throw new InvalidArgumentException(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__)); - } - // @codeCoverageIgnoreEnd - - $this->unserialize($data['string']); - } - - public function jsonSerialize(): string - { - return $this->toString(); - } - - private function prepareValue(string $value): string - { - if (!filter_var($value, FILTER_VALIDATE_EMAIL)) { - throw new InvalidArgumentException( - sprintf('Value must be a valid email address: %s', $value) - ); - } - - return $value; - } - - public static function fromString(string $value): self - { - return new self($value); - } -} diff --git a/src/App/Mailing/src/Exception/InvalidArgumentException.php b/src/App/Mailing/src/Exception/InvalidArgumentException.php deleted file mode 100644 index f0b3ddc5..00000000 --- a/src/App/Mailing/src/Exception/InvalidArgumentException.php +++ /dev/null @@ -1,7 +0,0 @@ -from($this->senderEmail->toString()) - ->to($email->toString()) - ->subject($subject) - ->text($plainText) - ->html($html); - - $this->mailer->send($email); - } -} diff --git a/src/App/Mailing/src/Infrastructure/EmailServiceFactory.php b/src/App/Mailing/src/Infrastructure/EmailServiceFactory.php deleted file mode 100644 index b57e32ca..00000000 --- a/src/App/Mailing/src/Infrastructure/EmailServiceFactory.php +++ /dev/null @@ -1,18 +0,0 @@ -get(MailerInterface::class); - $senderEmail = new EmailType($container->get('config')['project']['senderEmail']); - - return new EmailService($mailer, $senderEmail); - } -} diff --git a/src/App/Mailing/src/Infrastructure/Validator/EMailValidator.php b/src/App/Mailing/src/Infrastructure/Validator/EMailValidator.php deleted file mode 100644 index f9d6ed01..00000000 --- a/src/App/Mailing/src/Infrastructure/Validator/EMailValidator.php +++ /dev/null @@ -1,15 +0,0 @@ -add($this->emailInput); - } -} diff --git a/src/App/Mailing/src/Infrastructure/Validator/Input/EmailInput.php b/src/App/Mailing/src/Infrastructure/Validator/Input/EmailInput.php deleted file mode 100644 index efd1b4e7..00000000 --- a/src/App/Mailing/src/Infrastructure/Validator/Input/EmailInput.php +++ /dev/null @@ -1,26 +0,0 @@ -setRequired(true); - - $this->getFilterChain()->attachByName('StringTrim'); - - $this->getValidatorChain()->attachByName( - 'EmailAddress', - [ - 'hostnameValidator' => new Hostname(), - 'useMxCheck' => true, - ] - ); - } -} diff --git a/src/App/Shared/src/Domain/Workspace/WorkspaceCreatorInterface.php b/src/App/Shared/src/Domain/Workspace/WorkspaceCreatorInterface.php index 56b00e88..a3a39436 100644 --- a/src/App/Shared/src/Domain/Workspace/WorkspaceCreatorInterface.php +++ b/src/App/Shared/src/Domain/Workspace/WorkspaceCreatorInterface.php @@ -2,7 +2,7 @@ namespace ownHackathon\Shared\Domain\Workspace; -use Exdrals\Shared\Domain\Account\AccountInterface; +use Exdrals\Identity\Domain\AccountInterface; use ownHackathon\Workspace\DTO\WorkspaceRequest; interface WorkspaceCreatorInterface diff --git a/src/Shared/src/Handler/PingHandler.php b/src/App/Shared/src/Handler/PingHandler.php similarity index 97% rename from src/Shared/src/Handler/PingHandler.php rename to src/App/Shared/src/Handler/PingHandler.php index 0bd47243..62f1e432 100644 --- a/src/Shared/src/Handler/PingHandler.php +++ b/src/App/Shared/src/Handler/PingHandler.php @@ -1,6 +1,6 @@ $this->getDependencies(), - ConfigAbstractFactory::class => $this->getAbstractFactoryConfig(), - ]; - } - - public function getDependencies(): array - { - return [ - 'invokables' => [ - ], - 'aliases' => [ - ], - 'factories' => [ - Infrastructure\Factory\ErrorResponseFactory::class => ConfigAbstractFactory::class, - Middleware\ApiErrorHandlerMiddleware::class => ConfigAbstractFactory::class, - Middleware\RouteNotFoundMiddleware::class => ConfigAbstractFactory::class, - Shared\Infrastructure\Service\SlugService::class => InvokableFactory::class, - Shared\Middleware\RequireLoginMiddleware::class => InvokableFactory::class, - Shared\Middleware\FluentTransactionMiddleware::class => ConfigAbstractFactory::class, - ], - ]; - } - - public function getAbstractFactoryConfig(): array - { - return [ - Infrastructure\Factory\ErrorResponseFactory::class => [ - LoggerInterface::class, - ], - Middleware\ApiErrorHandlerMiddleware::class => [ - Infrastructure\Factory\ErrorResponseFactory::class, - ], - Middleware\RouteNotFoundMiddleware::class => [ - LoggerInterface::class, - ], - Shared\Middleware\FluentTransactionMiddleware::class => [ - Query::class, - ], - ]; - } -} diff --git a/src/Shared/src/Domain/Account/AccountAccessAuthCollectionInterface.php b/src/Shared/src/Domain/Account/AccountAccessAuthCollectionInterface.php deleted file mode 100644 index 2050569c..00000000 --- a/src/Shared/src/Domain/Account/AccountAccessAuthCollectionInterface.php +++ /dev/null @@ -1,16 +0,0 @@ - 'Eigentümer', - AccountRoles::Administrator => 'Administrator', - AccountRoles::Moderator => 'Moderator', - AccountRoles::User => 'Benutzer', - AccountRoles::Guest => 'Gast' - }; - } -} diff --git a/src/Shared/src/Domain/Enum/Account/AccountVisibleStatus.php b/src/Shared/src/Domain/Enum/Account/AccountVisibleStatus.php deleted file mode 100644 index 6b1d6676..00000000 --- a/src/Shared/src/Domain/Enum/Account/AccountVisibleStatus.php +++ /dev/null @@ -1,23 +0,0 @@ - 'online', - AccountVisibleStatus::NOT_PRESENT => 'Abwesend', - AccountVisibleStatus::DO_NOT_DISTURB => 'Bitte nicht stören', - AccountVisibleStatus::GHOST => 'unsichtbar', - AccountVisibleStatus::PERSONALIZED => 'personalisiert' - }; - } -} diff --git a/src/Shared/src/Domain/Enum/DataType.php b/src/Shared/src/Domain/Enum/DataType.php deleted file mode 100644 index 7b7cae14..00000000 --- a/src/Shared/src/Domain/Enum/DataType.php +++ /dev/null @@ -1,19 +0,0 @@ -getHttpStatusCode(), $previous); - $this->context = $context; - $this->responseMessage = $responseMessage; - $this->logLevel = $loglevel; - } - - abstract public function getHttpStatusCode(): int; - - public function getContext(): array - { - return $this->context; - } - - public function getResponseMessage(): string - { - return $this->responseMessage; - } - - public function getLogLevel(): Level - { - return $this->logLevel; - } -} diff --git a/src/Shared/src/Domain/Exception/HttpHandledInvalidArgumentAsSuccessException.php b/src/Shared/src/Domain/Exception/HttpHandledInvalidArgumentAsSuccessException.php deleted file mode 100644 index 5eae734e..00000000 --- a/src/Shared/src/Domain/Exception/HttpHandledInvalidArgumentAsSuccessException.php +++ /dev/null @@ -1,25 +0,0 @@ -get('config')['database']; - - $dsn = $settings['driver'] === 'mysql' - ? 'mysql:dbname=' . $settings['dbname'] . ';host=' . $settings['host'] . ';port=' . $settings['port'] - . ';charset=utf8mb4' - : 'sqlite:' . $settings['host']; - $user = $settings['user']; - $password = $settings['password']; - $options = [ - PDO::ATTR_ERRMODE => $settings['error'], - PDO::ATTR_EMULATE_PREPARES => $settings['emulate_prepares'], - ]; - - return new PDO($dsn, $user, $password, $options); - } -} diff --git a/src/Shared/src/Infrastructure/Factory/ErrorResponseFactory.php b/src/Shared/src/Infrastructure/Factory/ErrorResponseFactory.php deleted file mode 100644 index 8cbe30c5..00000000 --- a/src/Shared/src/Infrastructure/Factory/ErrorResponseFactory.php +++ /dev/null @@ -1,51 +0,0 @@ -getHttpStatusCode(); - $logLevel = $e->getLogLevel(); - $logContext = $e->getContext(); - $responseMessage = $e->getResponseMessage(); - - $this->logger->log( - $logLevel->value, - sprintf('[%d] %s', $statusCode, $e->getMessage()), - $logContext - ); - } else { - $this->logger->log( - Level::Critical, - sprintf('[%d] Unhandled exception %s', $statusCode, $e->getMessage()), - ['exception' => $e] - ); - } - - $message = HttpResponseMessage::create($statusCode, $responseMessage); - return new JsonResponse($message, $message->statusCode); - } -} diff --git a/src/Shared/src/Infrastructure/Factory/MailFactory.php b/src/Shared/src/Infrastructure/Factory/MailFactory.php deleted file mode 100644 index 272d3ecf..00000000 --- a/src/Shared/src/Infrastructure/Factory/MailFactory.php +++ /dev/null @@ -1,19 +0,0 @@ -get('config'); - - $settings = $settings['mailer']; - return new Mailer(Transport::fromDsn($settings['dsn'])); - } -} diff --git a/src/Shared/src/Infrastructure/Factory/QueryFactory.php b/src/Shared/src/Infrastructure/Factory/QueryFactory.php deleted file mode 100644 index 8465e8ff..00000000 --- a/src/Shared/src/Infrastructure/Factory/QueryFactory.php +++ /dev/null @@ -1,21 +0,0 @@ -get(PDO::class)); - } -} diff --git a/src/Shared/src/Infrastructure/Factory/UuidFactory.php b/src/Shared/src/Infrastructure/Factory/UuidFactory.php deleted file mode 100644 index 1d60fded..00000000 --- a/src/Shared/src/Infrastructure/Factory/UuidFactory.php +++ /dev/null @@ -1,13 +0,0 @@ -get('config')['logger']['path']; - - $date = (new DateTime())->format('Y-m-d'); - $path = rtrim($path, '/') . '/' . $date . '/'; - - if (!is_dir($path)) { - mkdir($path, 0775); - } - - $dateFormat = 'Y-m-d H:i:s'; - $output = "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"; - $formatter = new LineFormatter($output, $dateFormat); - $stackTraceFormater = clone $formatter; - $stackTraceFormater->includeStacktraces(true); - - $logger = new Logger('log'); - - $logger->pushHandler(new StreamHandler($path . 'default.log')->setFormatter($formatter)); - - $errorHandler = new StreamHandler($path . 'error.log', Level::Error)->setFormatter($formatter); - $errorHandler = new FilterHandler($errorHandler, Level::Error, Level::Error); - - $logger->pushHandler($errorHandler); - - $errorHandler = new StreamHandler($path . 'warning.log', Level::Warning)->setFormatter($formatter); - $errorHandler = new FilterHandler($errorHandler, Level::Error, Level::Error); - - $logger->pushHandler($errorHandler); - - $logger->pushHandler( - new StreamHandler($path . 'critical.log', Level::Critical)->setFormatter($stackTraceFormater) - ); - $logger->pushProcessor(new PsrLogMessageProcessor()); - $logger->pushProcessor( - new MetaDataProcessor( - filter_input(INPUT_SERVER, 'REMOTE_ADDR'), - filter_input(INPUT_SERVER, 'REQUEST_URI'), - filter_input(INPUT_SERVER, 'REQUEST_METHOD'), - filter_input(INPUT_SERVER, 'REDIRECT_URL'), - filter_input_array(INPUT_GET) - ) - ); - return $logger; - } -} diff --git a/src/Shared/src/Infrastructure/Logger/MetaDataProcessor.php b/src/Shared/src/Infrastructure/Logger/MetaDataProcessor.php deleted file mode 100644 index c9d6cae6..00000000 --- a/src/Shared/src/Infrastructure/Logger/MetaDataProcessor.php +++ /dev/null @@ -1,29 +0,0 @@ -extra['Remote'] = $this->remoteAddr; - $record->extra['URI'] = $this->uri; - $record->extra['Method'] = $this->method; - $record->extra['Redirect'] = $this->redirect; - $record->extra['Query'] = $this->query; - - return $record; - } -} diff --git a/src/Shared/src/Infrastructure/Persistence/AbstractTable.php b/src/Shared/src/Infrastructure/Persistence/AbstractTable.php deleted file mode 100644 index 621f8fcb..00000000 --- a/src/Shared/src/Infrastructure/Persistence/AbstractTable.php +++ /dev/null @@ -1,46 +0,0 @@ -table = substr(new ReflectionClass($this)->getShortName(), 0, -5); - $this->query = $query; - } - - public function getTableName(): string - { - return $this->table; - } - - /** - * @throws Exception - */ - public function deleteById(int $id): true - { - $result = $this->query->delete($this->table, $id)->execute(); - - if ($result === false) { - throw new InvalidArgumentException( - sprintf('Failed to delete %s table with id: `%s`', $this->getTableName(), $id) - ); - } - - return true; - } -} diff --git a/src/Shared/src/Infrastructure/Persistence/Contract/TransactionManagerInterface.php b/src/Shared/src/Infrastructure/Persistence/Contract/TransactionManagerInterface.php deleted file mode 100644 index fd6fcd49..00000000 --- a/src/Shared/src/Infrastructure/Persistence/Contract/TransactionManagerInterface.php +++ /dev/null @@ -1,12 +0,0 @@ -handle($request); - } catch (Throwable $e) { - return $this->errorResponseFactory->createFromThrowable($e); - } - } -} diff --git a/src/Shared/src/Middleware/FluentTransactionMiddleware.php b/src/Shared/src/Middleware/FluentTransactionMiddleware.php deleted file mode 100644 index 18645f2d..00000000 --- a/src/Shared/src/Middleware/FluentTransactionMiddleware.php +++ /dev/null @@ -1,48 +0,0 @@ -getMethod(), ['GET', 'HEAD'], true)) { - return $handler->handle($request); - } - - $pdo = $this->fluentPdo->getPdo(); - - if ($pdo->inTransaction()) { - return $handler->handle($request); - } - - $pdo->beginTransaction(); - - try { - $response = $handler->handle($request); - - $pdo->commit(); - - return $response; - } catch (Throwable $exception) { - // @phpstan-ignore-next-line - if ($pdo->inTransaction()) { - $pdo->rollBack(); - } - - throw $exception; - } - } -} diff --git a/src/Shared/src/Middleware/RequireLoginMiddleware.php b/src/Shared/src/Middleware/RequireLoginMiddleware.php deleted file mode 100644 index 37ea8e9c..00000000 --- a/src/Shared/src/Middleware/RequireLoginMiddleware.php +++ /dev/null @@ -1,31 +0,0 @@ -getAttribute(AccountInterface::AUTHENTICATED); - - if (!($account instanceof AccountInterface)) { - throw new HttpUnauthorizedException( - LogMessage::UNAUTHORIZED_ACCESS, - StatusMessage::UNAUTHORIZED_ACCESS, - [], - ); - } - - return $handler->handle($request); - } -} diff --git a/src/Shared/src/Middleware/RouteNotFoundMiddleware.php b/src/Shared/src/Middleware/RouteNotFoundMiddleware.php deleted file mode 100644 index 6ed59f72..00000000 --- a/src/Shared/src/Middleware/RouteNotFoundMiddleware.php +++ /dev/null @@ -1,24 +0,0 @@ -logger->notice('Route not found'); - - return $handler->handle($request); - } -} diff --git a/src/Shared/src/Trait/CloneReadonlyClassWith.php b/src/Shared/src/Trait/CloneReadonlyClassWith.php deleted file mode 100644 index 93d2caf8..00000000 --- a/src/Shared/src/Trait/CloneReadonlyClassWith.php +++ /dev/null @@ -1,16 +0,0 @@ -config->key, $this->config->algorithmus)); - } catch ( - InvalidArgumentException - | DomainException - | UnexpectedValueException - | SignatureInvalidException - | BeforeValidException - | ExpiredException $e - ) { - return false; - } - - return true; - } - - public function decode(string $token): object - { - if (!$this->isValid($token)) { - return throw new InvalidArgumentException(); - } - - return JWT::decode($token, new Key($this->config->key, $this->config->algorithmus)); - } -} diff --git a/src/Shared/src/Type/TypeInterface.php b/src/Shared/src/Type/TypeInterface.php deleted file mode 100644 index 5eebef26..00000000 --- a/src/Shared/src/Type/TypeInterface.php +++ /dev/null @@ -1,13 +0,0 @@ - $collection - */ - protected array $collection = []; - private int $position = 0; - - public function offsetExists(mixed $offset): bool - { - return isset($this->collection[$offset]); - } - - /** - * @throws UndefinedOffsetException - */ - public function offsetGet(mixed $offset): mixed - { - if (!$this->offsetExists($offset)) { - throw new UndefinedOffsetException( - sprintf('Undefined offset: %s in Collection %s on Line %s', $offset, __FILE__, __LINE__) - ); - } - - return $this->collection[$offset]; - } - - public function offsetSet(mixed $offset, mixed $value): void - { - is_null($offset) - ? $this->collection[] = $value - : $this->collection[$offset] = $value; - } - - public function offsetUnset(mixed $offset): void - { - unset($this->collection[$offset]); - } - - public function current(): mixed - { - return $this->collection[$this->position]; - } - - public function next(): void - { - $this->position++; - } - - public function key(): int - { - return $this->position; - } - - public function valid(): bool - { - return $this->offsetExists($this->position); - } - - public function rewind(): void - { - $this->position = 0; - } - - public function count(): int - { - return count($this->collection); - } - - public function first(): mixed - { - $collection = $this->collection; - return array_shift($collection); - } - - public function last(): mixed - { - $collection = $this->collection; - return array_pop($collection); - } - - /** - * @return array - */ - public function filter(Closure $function): array - { - return array_filter($this->collection, $function); - } - - public function getElements(): array - { - return $this->collection; - } - - public function jsonSerialize(): array - { - return $this->getElements(); - } -} diff --git a/src/Shared/src/Utils/CollectionInterface.php b/src/Shared/src/Utils/CollectionInterface.php deleted file mode 100644 index 8b058bfd..00000000 --- a/src/Shared/src/Utils/CollectionInterface.php +++ /dev/null @@ -1,12 +0,0 @@ -createJsonPostRequest( - '/api/account/activation/' . $accountActivate['token'], - [ - 'accountName' => Faker::create()->unique()->name(), - 'password' => Faker::create()->password(8), - ] - ); - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_CREATED) - ->and('Account')->toHaveRecord(['email' => $accountActivate['email']]); -}); - -it('returns 400 when body is empty', function () { - $accountActivation = AccountActivationFactory::create(); - $request = $this->createJsonPostRequest( - '/api/account/activation/' . $accountActivation['token'], - [], - ); - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_BAD_REQUEST); -}); - -it('returns 400 when not token was assigned', function () { - $request = $this->createJsonPostRequest( - '/api/account/activation/', - [ - 'accountName' => Faker::create()->unique()->name(), - 'password' => Faker::create()->password(8), - ] - ); - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_BAD_REQUEST); -}); - -it('returns 400 if the account name is invalid', function () { - $accountActivation = AccountActivationFactory::create(); - $request = $this->createJsonPostRequest( - '/api/account/activation/' . $accountActivation['token'], - [ - 'accountName' => Faker::create()->lexify('??'), - 'password' => Faker::create()->password(8), - ] - ); - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_BAD_REQUEST); -}); - -it('returns 400 if the password is invalid', function () { - $accountActivation = AccountActivationFactory::create(); - $request = $this->createJsonPostRequest( - '/api/account/activation/' . $accountActivation['token'], - [ - 'accountName' => Faker::create()->name(), - 'password' => Faker::create()->password(1, 5), - ] - ); - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_BAD_REQUEST); -}); - -it('returns 400 because token not found', function () { - $request = $this->createJsonPostRequest( - '/api/account/activation/' . Faker::create()->uuid(), - [ - 'accountName' => Faker::create()->name(), - 'password' => Faker::create()->password(8), - ] - ); - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_BAD_REQUEST); -}); - -it('returns 409 when Accountname is duplicate', function () { - $accountActivation = AccountActivationFactory::create(); - $account = AccountFactory::create(); - - $request = $this->createJsonPostRequest( - '/api/account/activation/' . $accountActivation['token'], - [ - 'accountName' => $account['name'], - 'password' => Faker::create()->password(8), - ] - ); - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_CONFLICT); -}); diff --git a/tests/Integration/App/Account/Identity/AuthenticationTest.php b/tests/Integration/App/Account/Identity/AuthenticationTest.php deleted file mode 100644 index 6c42ed61..00000000 --- a/tests/Integration/App/Account/Identity/AuthenticationTest.php +++ /dev/null @@ -1,188 +0,0 @@ -createJsonPostRequest( - '/api/account/authentication', - [ - 'email' => $account['email'], - 'password' => $account['password'], - ] - ); - - $modifiedRequest = RequestPipingFactory::process( - ClientIdentificationMiddleware::class, - $request - ); - - $clientIdentifikation = $modifiedRequest->getAttribute(ClientIdentification::class); - - $response = $this->app->handle($request); - $json = JsonFactory::create($response); - expect($response->getStatusCode())->toBe(Http::STATUS_OK) - ->and('AccountAccessAuth')->toHaveRecord([ - 'accountId' => $account['id'], - 'clientIdentHash' => $clientIdentifikation->identificationHash, - 'refreshToken' => $json['refreshToken'], - ]) - ->and(JsonFactory::create($response)) - ->toBeArray() - ->toHaveKey('refreshToken') - ->toHaveKey('accessToken'); -}); - -test('Login failed because authentication is already set in the header', function () { - $account = AccountFactory::create(); - $request = $this->createJsonPostRequest( - '/api/account/authentication', - [ - 'email' => $account['email'], - 'password' => $account['password'], - ] - ) - ->withAddedHeader('x-ident', (string)rand()) - ->withAddedHeader('Authorization', 'Authorization'); - - $response = $this->app->handle($request); - - expect($response->getStatusCode())->toBe(Http::STATUS_UNAUTHORIZED); -}); - -test('Login failed because there is already a login entry with the same identification in the database', function () { - $account = AccountFactory::create(); - $firstRequest = $this->createJsonPostRequest( - '/api/account/authentication', - [ - 'email' => $account['email'], - 'password' => $account['password'], - ] - ); - $secondRequest = $this->createJsonPostRequest( - '/api/account/authentication', - [ - 'email' => $account['email'], - 'password' => $account['password'], - ] - ); - - $this->app->handle($firstRequest); - $response = $this->app->handle($secondRequest); - - expect($response->getStatusCode())->toBe(Http::STATUS_CONFLICT); -}); - -test('Account can log in with different identifications at the same time', function () { - $account = AccountFactory::create(); - $firstRequest = $this->createJsonPostRequest( - '/api/account/authentication', - [ - 'email' => $account['email'], - 'password' => $account['password'], - ] - ) - ->withHeader('x-ident', (string)rand()); - - $secondRequest = $this->createJsonPostRequest( - '/api/account/authentication', - [ - 'email' => $account['email'], - 'password' => $account['password'], - ] - ) - ->withHeader('x-ident', (string)rand()); - - $modifiedFirstRequest = RequestPipingFactory::process( - ClientIdentificationMiddleware::class, - $firstRequest - ); - $modifiedSecondRequest = RequestPipingFactory::process( - ClientIdentificationMiddleware::class, - $secondRequest - ); - - $firstClientIdentifikation = $modifiedFirstRequest->getAttribute(ClientIdentification::class); - $secondClientIdentifikation = $modifiedSecondRequest->getAttribute(ClientIdentification::class); - - $this->app->handle($firstRequest); - $response = $this->app->handle($secondRequest); - - expect($response->getStatusCode())->toBe(Http::STATUS_OK) - ->and($firstClientIdentifikation->identificationHash)->not->toBe( - $secondClientIdentifikation->identificationHash - ) - ->and('AccountAccessAuth')->toHaveRecord([ - 'accountId' => $account['id'], - 'clientIdentHash' => $firstClientIdentifikation->identificationHash, - ]) - ->and('AccountAccessAuth')->toHaveRecord([ - 'accountId' => $account['id'], - 'clientIdentHash' => $secondClientIdentifikation->identificationHash, - ]); -}); - -test('Credentials have invalid email', function () { - $request = $this->createJsonPostRequest( - '/api/account/authentication', - [ - 'email' => Faker::create()->regexify('[a-z]{5}-at-[a-z]{5}\.de'), - 'password' => Faker::create()->password(8), - ] - ); - - $response = $this->app->handle($request); - - expect($response->getStatusCode())->toBe(Http::STATUS_UNAUTHORIZED); -}); - -test('Credentials have invalid password', function () { - $account = AccountFactory::create(); - $request = $this->createJsonPostRequest( - '/api/account/authentication', - [ - 'email' => $account['email'], - 'password' => Faker::create()->password(1, 5), - ] - ); - - $response = $this->app->handle($request); - - expect($response->getStatusCode())->toBe(Http::STATUS_UNAUTHORIZED); -}); - -test('Credentials are missed', function () { - $request = $this->createJsonPostRequest( - '/api/account/authentication', - [ - ] - ); - - $response = $this->app->handle($request); - - expect($response->getStatusCode())->toBe(Http::STATUS_UNAUTHORIZED); -}); - -test('Account missing', function () { - $request = $this->createJsonPostRequest( - '/api/account/authentication', - [ - 'email' => Faker::create()->safeEmail(), - 'password' => Faker::create()->password(8), - ] - ); - - $response = $this->app->handle($request); - - expect($response->getStatusCode())->toBe(Http::STATUS_UNAUTHORIZED); -}); diff --git a/tests/Integration/App/Account/Identity/LogoutTest.php b/tests/Integration/App/Account/Identity/LogoutTest.php deleted file mode 100644 index eb1c2b05..00000000 --- a/tests/Integration/App/Account/Identity/LogoutTest.php +++ /dev/null @@ -1,120 +0,0 @@ -createJsonPostRequest( - '/api/account/authentication', - [ - 'email' => $account['email'], - 'password' => $account['password'], - ] - ); - $response = $this->app->handle($request); - $jsonResponse = JsonFactory::create($response); - - $request = $this->createJsonPostRequest( - '/api/account/logout', - [ - 'refreshToken' => $jsonResponse['refreshToken'], - ] - ) - ->withHeader('Authorization', $jsonResponse['accessToken']); - - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_NO_CONTENT) - ->and('AccountAccessAuth')->toNotHaveRecord(['refreshToken' => $jsonResponse['refreshToken']]); -}); - -test('Access Token invalid', function () { - $account = AccountFactory::create(); - $request = $this->createJsonPostRequest( - '/api/account/authentication', - [ - 'email' => $account['email'], - 'password' => $account['password'], - ] - ); - $response = $this->app->handle($request); - $jsonResponse = JsonFactory::create($response); - - $request = $this->createJsonPostRequest( - '/api/account/logout', - [ - 'refreshToken' => $jsonResponse['refreshToken'], - ] - ) - ->withHeader('Authorization', $jsonResponse['refreshToken']); - - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_UNAUTHORIZED); -}); - -test('Refresh Token invalid', function () { - $account = AccountFactory::create(); - $request = $this->createJsonPostRequest( - '/api/account/authentication', - [ - 'email' => $account['email'], - 'password' => $account['password'], - ] - ); - $response = $this->app->handle($request); - $jsonResponse = JsonFactory::create($response); - $request = $this->createJsonPostRequest( - '/api/account/logout', - [ - 'refreshToken' => $jsonResponse['accessToken'], - ] - ) - ->withHeader('Authorization', $jsonResponse['accessToken']); - - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_UNAUTHORIZED); -}); - -it('has not authorization', function () { - $account = AccountFactory::create(); - $request = $this->createJsonPostRequest( - '/api/account/authentication', - [ - 'email' => $account['email'], - 'password' => $account['password'], - ] - ); - $response = $this->app->handle($request); - $jsonResponse = JsonFactory::create($response); - $request = $this->createJsonPostRequest( - '/api/account/logout', - [ - 'refreshToken' => $jsonResponse['accessToken'], - ] - ); - - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_UNAUTHORIZED); -}); - -it('has no body content', function () { - $account = AccountFactory::create(); - $request = $this->createJsonPostRequest( - '/api/account/authentication', - [ - 'email' => $account['email'], - 'password' => $account['password'], - ] - ); - $response = $this->app->handle($request); - $jsonResponse = JsonFactory::create($response); - $request = $this->createJsonPostRequest( - '/api/account/logout', - [] - ) - ->withHeader('Authorization', $jsonResponse['accessToken']); - - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_UNAUTHORIZED); -}); diff --git a/tests/Integration/App/Account/Identity/PasswordChangeTest.php b/tests/Integration/App/Account/Identity/PasswordChangeTest.php deleted file mode 100644 index aedb4456..00000000 --- a/tests/Integration/App/Account/Identity/PasswordChangeTest.php +++ /dev/null @@ -1,99 +0,0 @@ -createJsonPatchRequest( - '/api/account/password/' . $passwordChange['token'], - [ - 'password' => Faker::create('de_DE')->password(8), - ] - ); - - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_OK) - ->and('Token')->toNotHaveRecord(['token' => $passwordChange['token']]); -}); - -test('Can not use the same token twice', function () { - $passwordChange = PasswordChangeFactory::create(); - - $request = $this->createJsonPatchRequest( - '/api/account/password/' . $passwordChange['token'], - [ - 'password' => Faker::create('de_DE')->password(8), - ] - ); - - $this->app->handle($request); - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_BAD_REQUEST) - ->and('Token')->toNotHaveRecord(['token' => $passwordChange['token']]); -}); - - - -test('Token present in the database but account does not exist', function () { - $passwordChange = PasswordChangeFactory::create(); - $fluent = $this->getContainer()->get(Query::class); - $fluent->deleteFrom('Token')->where('accountId', $passwordChange['accountId'])->execute(); - - $request = $this->createJsonPatchRequest( - '/api/account/password/' . $passwordChange['token'], - [ - 'password' => Faker::create('de_DE')->password(8), - ] - ); - - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_BAD_REQUEST); -}); - -test('Token is invalid', function () { - PasswordChangeFactory::create(); - - $request = $this->createJsonPatchRequest( - '/api/account/password/' . Faker::create('de_DE')->uuid(), - [ - 'password' => Faker::create('de_DE')->password(8), - ] - ); - - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_BAD_REQUEST); -}); - -test('Token has incorrect type', function () { - $passwordChange = PasswordChangeFactory::create([ - 'tokenType' => \Exdrals\Shared\Domain\Enum\Token\TokenType::Default->value, - ]); - - $request = $this->createJsonPatchRequest( - '/api/account/password/' . $passwordChange['token'], - [ - 'password' => Faker::create('de_DE')->password(8), - ] - ); - - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_BAD_REQUEST); -}); - -test('New password invalid', function () { - $passwordChange = PasswordChangeFactory::create(); - - $request = $this->createJsonPatchRequest( - '/api/account/password/' . $passwordChange['token'], - [ - 'password' => Faker::create('de_DE')->password(1, 5), - ] - ); - - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_BAD_REQUEST); -}); diff --git a/tests/Integration/App/Account/Identity/PasswordForgottenTest.php b/tests/Integration/App/Account/Identity/PasswordForgottenTest.php deleted file mode 100644 index 8088c00f..00000000 --- a/tests/Integration/App/Account/Identity/PasswordForgottenTest.php +++ /dev/null @@ -1,70 +0,0 @@ -createJsonPostRequest( - '/api/account/password/forgotten', - ['email' => $account['email']] - ); - - $service = $this->container->get(PasswordService::class); - - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(200) - ->and(fn() => $service->sendTokenForInitiateResetPassword( - EmailType::fromString($account['email']) - )) - ->not->toThrow(HttpHandledInvalidArgumentAsSuccessException::class); -}); - -it('returns 200, despite an invalid email address being provided', function () { - $email = Faker::create()->safeEmail(); - - $request = $this->createJsonPostRequest( - '/api/account/password/forgotten', - ['email' => $email] - ); - - $service = $this->container->get(PasswordService::class); - - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(200) - ->and(fn() => $service->sendTokenForInitiateResetPassword( - EmailType::fromString($email) - )) - ->toThrow(HttpHandledInvalidArgumentAsSuccessException::class); -}); - -it('returns 400 when email is invalid', function ($email) { - $request = $this->createJsonPostRequest( - '/api/account/password/forgotten', - [ - 'email' => $email, - ] - ); - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_BAD_REQUEST); -})->with([ - 'invalidate.com', - 'user@', - '@domain.com', - 'user..name@domain.com', - 'user:name@domain.com', - 'user@domain!.com', - 'user@domain', - 'user name@domain.com', - 'user@domain .com', - 'user@domain..com', - 'user@-domain.com', - 'test@example.invalid', - 'test@example.web', -]); diff --git a/tests/Integration/App/Account/Identity/RegisterTest.php b/tests/Integration/App/Account/Identity/RegisterTest.php deleted file mode 100644 index 042ef124..00000000 --- a/tests/Integration/App/Account/Identity/RegisterTest.php +++ /dev/null @@ -1,86 +0,0 @@ -safeEmail(); - $request = $this->createJsonPostRequest( - '/api/account', - [ - 'email' => $email, - ] - ); - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_OK) - ->and('AccountActivation')->toHaveRecord(['email' => $email]); -}); - - -it('returns 400 when email is invalid', function ($email) { - $request = $this->createJsonPostRequest( - '/api/account', - [ - 'email' => $email, - ] - ); - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_BAD_REQUEST); -})->with([ - 'invalidate.com', - 'user@', - '@domain.com', - 'user..name@domain.com', - 'user:name@domain.com', - 'user@domain!.com', - 'user@domain', - 'user name@domain.com', - 'user@domain .com', - 'user@domain..com', - 'user@-domain.com', - 'test@example.invalid', - 'test@example.web', -]); - -it('handles service exceptions through mapping middleware', function () { - $service = Mockery::mock(AccountRegisterServiceInterface::class); - $service->shouldReceive('register') - ->andThrow(new Exception('Database connection failed')); - $this->container->setService(AccountRegisterServiceInterface::class, $service); - $request = $this->createJsonPostRequest( - '/api/account', - [ - 'email' => Faker::create()->safeEmail(), - ] - ); - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_OK); -}); - -it('returns 400 when body is empty', function () { - $request = $this->createJsonPostRequest( - '/api/account', - [], - ); - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_BAD_REQUEST); -}); - -it('returns 400 when email address is duplicate', function () { - $account = AccountFactory::create(); - $request = $this->createJsonPostRequest( - '/api/account', - [ - 'email' => $account['email'], - ] - ); - $response = $this->app->handle($request); - expect($response->getStatusCode())->toBe(Http::STATUS_OK) - ->and('Account')->toHaveRecord(['email' => $account['email']]); -}); diff --git a/tests/Integration/App/Account/Identity/TokenRefreshTest.php b/tests/Integration/App/Account/Identity/TokenRefreshTest.php deleted file mode 100644 index d7fb36a5..00000000 --- a/tests/Integration/App/Account/Identity/TokenRefreshTest.php +++ /dev/null @@ -1,119 +0,0 @@ -createJsonPostRequest( - '/api/account/authentication', - [ - 'email' => $account['email'], - 'password' => $account['password'], - ] - ); - - $response = $this->app->handle($request); - $json = JsonFactory::create($response); - - $request = $this->createGetRequest( - '/api/token/refresh' - ) - ->withHeader('Authentication', $json['refreshToken']); - - $response = $this->app->handle($request); - - expect($response->getStatusCode())->toBe(Http::STATUS_OK) - ->and(JsonFactory::create($response)) - ->toBeArray() - ->toHaveKey('accessToken'); -}); - -test('Refresh token is invalid', function () { - $account = AccountFactory::create(); - $request = $this->createGetRequest( - '/api/token/refresh' - ) - ->withHeader('Authentication', INVALID_TOKEN); - - $modifiedRequest = RequestPipingFactory::process( - ClientIdentificationMiddleware::class, - $request - ); - - $clientIdentifikation = $modifiedRequest->getAttribute(ClientIdentification::class); - - AccountAccessAuthFactory::create([ - 'accountId' => $account['id'], - 'refreshToken' => EXPIRED_TOKEN, - 'clientIdentHash' => $clientIdentifikation->identificationHash, - ]); - - $response = $this->app->handle($request); - - expect($response->getStatusCode())->toBe(Http::STATUS_UNAUTHORIZED); -}); - -test('Refresh Token is expired', function () { - $account = AccountFactory::create(); - $request = $this->createGetRequest( - '/api/token/refresh' - ) - ->withHeader('Authentication', EXPIRED_TOKEN); - - $modifiedRequest = RequestPipingFactory::process( - ClientIdentificationMiddleware::class, - $request - ); - - $clientIdentifikation = $modifiedRequest->getAttribute(ClientIdentification::class); - - AccountAccessAuthFactory::create([ - 'accountId' => $account['id'], - 'refreshToken' => EXPIRED_TOKEN, - 'clientIdentHash' => $clientIdentifikation->identificationHash, - ]); - - $response = $this->app->handle($request); - - expect($response->getStatusCode())->toBe(Http::STATUS_UNAUTHORIZED); -}); - -test('Refresh token not found', function () { - $account = AccountFactory::create(); - $request = $this->createJsonPostRequest( - '/api/account/authentication', - [ - 'email' => $account['email'], - 'password' => $account['password'], - ] - ); - - $response = $this->app->handle($request); - $json = JsonFactory::create($response); - - $request = $this->createGetRequest( - '/api/token/refresh' - ) - ->withHeader('Authentication', $json['refreshToken']); - - $fluent = $this->getContainer()->get(Query::class); - - $fluent->delete('AccountAccessAuth')->where('accountId', $account['id'])->execute(); - - $response = $this->app->handle($request); - - expect($response->getStatusCode())->toBe(Http::STATUS_UNAUTHORIZED); -}); diff --git a/tests/Integration/App/Account/Identity/Factory/AccountAccessAuthFactory.php b/tests/Integration/App/Factory/AccountAccessAuthFactory.php similarity index 94% rename from tests/Integration/App/Account/Identity/Factory/AccountAccessAuthFactory.php rename to tests/Integration/App/Factory/AccountAccessAuthFactory.php index 7be71cc3..d4ada504 100644 --- a/tests/Integration/App/Account/Identity/Factory/AccountAccessAuthFactory.php +++ b/tests/Integration/App/Factory/AccountAccessAuthFactory.php @@ -1,6 +1,6 @@