diff --git a/backend/.phpunit.cache/test-results b/backend/.phpunit.cache/test-results new file mode 100644 index 0000000..1a881e2 --- /dev/null +++ b/backend/.phpunit.cache/test-results @@ -0,0 +1 @@ +{"version":2,"defects":{"Tests\\Unit\\Auth\\UseCases\\AuthenticateUserTest::testAuthenticatesWithValidCredentials":8,"Tests\\Unit\\Auth\\UseCases\\AuthenticateUserTest::testThrowsBadRequestWhenEmailIsEmpty":8,"Tests\\Unit\\Auth\\UseCases\\AuthenticateUserTest::testThrowsBadRequestWhenPasswordIsEmpty":8,"Tests\\Unit\\Auth\\UseCases\\AuthenticateUserTest::testThrowsBadRequestWhenEmailIsNull":8,"Tests\\Unit\\Auth\\UseCases\\AuthenticateUserTest::testThrowsBadRequestWhenPasswordIsNull":8,"Tests\\Unit\\Auth\\UseCases\\AuthenticateUserTest::testThrowsUnauthorizedForUnknownEmail":8,"Tests\\Unit\\Auth\\UseCases\\AuthenticateUserTest::testThrowsUnauthorizedForWrongPassword":8,"Tests\\Unit\\Auth\\UseCases\\AuthenticateUserTest::testReturnsNewInstanceOnEachCall":8,"Tests\\Unit\\Auth\\UseCases\\CreateSessionTest::testCreatesSessionWithGivenToken":8,"Tests\\Unit\\Auth\\UseCases\\CreateSessionTest::testCreatesSessionWithUser":8,"Tests\\Unit\\Auth\\UseCases\\CreateSessionTest::testCreatesSessionWithCreatedAtFromClock":8,"Tests\\Unit\\Auth\\UseCases\\CreateSessionTest::testCreatesSessionWithExpirySevenDaysLater":8,"Tests\\Unit\\Auth\\UseCases\\CreateSessionTest::testPersistsSessionInRepository":8,"Tests\\Unit\\Auth\\UseCases\\CreateSessionTest::testFreshInstanceReturnedOnEachCall":8,"Tests\\Unit\\Auth\\UseCases\\LogoutTest::testDeletesSessionByToken":8,"Tests\\Unit\\Auth\\UseCases\\LogoutTest::testDoesNotThrowForUnknownToken":8,"Tests\\Unit\\Middleware\\AuthMiddlewareTest::testPassesRequestToHandlerWhenCookieIsValid":8,"Tests\\Unit\\Middleware\\AuthMiddlewareTest::testReturns401WhenCookieIsMissing":8,"Tests\\Unit\\Middleware\\AuthMiddlewareTest::testReturns401WhenCookieIsEmpty":8,"Tests\\Unit\\Middleware\\AuthMiddlewareTest::testReturns401WhenTokenIsUnknown":8,"Tests\\Unit\\Middleware\\AuthMiddlewareTest::testReturns401WhenSessionIsExpired":8,"Tests\\Unit\\Middleware\\AuthMiddlewareTest::testDeletesExpiredSession":8,"Tests\\Unit\\Controllers\\AuthControllerTest::testLoginReturnsUserAndSetsCookie":8,"Tests\\Unit\\Controllers\\AuthControllerTest::testLoginReturns400ForMissingEmail":8,"Tests\\Unit\\Controllers\\AuthControllerTest::testLoginReturns401ForInvalidCredentials":8,"Tests\\Unit\\Controllers\\AuthControllerTest::testLogoutClearsCookieAndReturns204":8,"Tests\\Unit\\Controllers\\AuthControllerTest::testMeReturnsUserFromAttribute":8},"times":{"Tests\\Unit\\Auth\\UseCases\\AuthenticateUserTest::testAuthenticatesWithValidCredentials":0.001,"Tests\\Unit\\Auth\\UseCases\\AuthenticateUserTest::testThrowsBadRequestWhenEmailIsEmpty":0,"Tests\\Unit\\Auth\\UseCases\\AuthenticateUserTest::testThrowsBadRequestWhenPasswordIsEmpty":0,"Tests\\Unit\\Auth\\UseCases\\AuthenticateUserTest::testThrowsBadRequestWhenEmailIsNull":0,"Tests\\Unit\\Auth\\UseCases\\AuthenticateUserTest::testThrowsBadRequestWhenPasswordIsNull":0,"Tests\\Unit\\Auth\\UseCases\\AuthenticateUserTest::testThrowsUnauthorizedForUnknownEmail":0,"Tests\\Unit\\Auth\\UseCases\\AuthenticateUserTest::testThrowsUnauthorizedForWrongPassword":0,"Tests\\Unit\\Auth\\UseCases\\AuthenticateUserTest::testReturnsNewInstanceOnEachCall":0,"Tests\\Unit\\Auth\\UseCases\\CreateSessionTest::testCreatesSessionWithGivenToken":0,"Tests\\Unit\\Auth\\UseCases\\CreateSessionTest::testCreatesSessionWithUser":0,"Tests\\Unit\\Auth\\UseCases\\CreateSessionTest::testCreatesSessionWithCreatedAtFromClock":0,"Tests\\Unit\\Auth\\UseCases\\CreateSessionTest::testCreatesSessionWithExpirySevenDaysLater":0,"Tests\\Unit\\Auth\\UseCases\\CreateSessionTest::testPersistsSessionInRepository":0,"Tests\\Unit\\Auth\\UseCases\\CreateSessionTest::testFreshInstanceReturnedOnEachCall":0,"Tests\\Unit\\Auth\\UseCases\\LogoutTest::testDeletesSessionByToken":0,"Tests\\Unit\\Auth\\UseCases\\LogoutTest::testDoesNotThrowForUnknownToken":0,"Tests\\Unit\\Middleware\\AuthMiddlewareTest::testPassesRequestToHandlerWhenCookieIsValid":0.001,"Tests\\Unit\\Middleware\\AuthMiddlewareTest::testReturns401WhenCookieIsMissing":0,"Tests\\Unit\\Middleware\\AuthMiddlewareTest::testReturns401WhenCookieIsEmpty":0.001,"Tests\\Unit\\Middleware\\AuthMiddlewareTest::testReturns401WhenTokenIsUnknown":0,"Tests\\Unit\\Middleware\\AuthMiddlewareTest::testReturns401WhenSessionIsExpired":0,"Tests\\Unit\\Middleware\\AuthMiddlewareTest::testDeletesExpiredSession":0,"Tests\\Unit\\Controllers\\AuthControllerTest::testLoginReturnsUserAndSetsCookie":0.001,"Tests\\Unit\\Controllers\\AuthControllerTest::testLoginReturns400ForMissingEmail":0,"Tests\\Unit\\Controllers\\AuthControllerTest::testLoginReturns401ForInvalidCredentials":0.006,"Tests\\Unit\\Controllers\\AuthControllerTest::testLogoutClearsCookieAndReturns204":0,"Tests\\Unit\\Controllers\\AuthControllerTest::testMeReturnsUserFromAttribute":0}} \ No newline at end of file diff --git a/backend/app/Auth/CreateSessionDto.php b/backend/app/Auth/CreateSessionDto.php index 2e5e2f7..d22b708 100644 --- a/backend/app/Auth/CreateSessionDto.php +++ b/backend/app/Auth/CreateSessionDto.php @@ -12,5 +12,6 @@ class CreateSessionDto public User $user, public DateTimeImmutable $createdAt, public DateTimeImmutable $expiresAt, - ) {} + ) { + } } diff --git a/backend/app/Auth/Session.php b/backend/app/Auth/Session.php index b433114..b95905b 100644 --- a/backend/app/Auth/Session.php +++ b/backend/app/Auth/Session.php @@ -12,7 +12,8 @@ class Session private User $user, private DateTimeImmutable $createdAt, private DateTimeImmutable $expiresAt, - ) {} + ) { + } public function getToken(): string { diff --git a/backend/app/Auth/UseCases/AuthenticateUser/AuthenticateUser.php b/backend/app/Auth/UseCases/AuthenticateUser/AuthenticateUser.php index 6899620..109447c 100644 --- a/backend/app/Auth/UseCases/AuthenticateUser/AuthenticateUser.php +++ b/backend/app/Auth/UseCases/AuthenticateUser/AuthenticateUser.php @@ -14,7 +14,8 @@ class AuthenticateUser public function __construct( private UserRepository $userRepo, private PasswordHasher $hasher, - ) {} + ) { + } /** * @throws BadRequestException diff --git a/backend/app/Auth/UseCases/AuthenticateUser/AuthenticateUserRequest.php b/backend/app/Auth/UseCases/AuthenticateUser/AuthenticateUserRequest.php index aa8b1df..d7cf6dd 100644 --- a/backend/app/Auth/UseCases/AuthenticateUser/AuthenticateUserRequest.php +++ b/backend/app/Auth/UseCases/AuthenticateUser/AuthenticateUserRequest.php @@ -7,5 +7,6 @@ class AuthenticateUserRequest public function __construct( public ?string $email, public ?string $password, - ) {} + ) { + } } diff --git a/backend/app/Auth/UseCases/CreateSession/CreateSession.php b/backend/app/Auth/UseCases/CreateSession/CreateSession.php index db6403f..83014a6 100644 --- a/backend/app/Auth/UseCases/CreateSession/CreateSession.php +++ b/backend/app/Auth/UseCases/CreateSession/CreateSession.php @@ -17,7 +17,8 @@ class CreateSession private SessionRepository $sessionRepo, private TokenGenerator $tokenGenerator, private Clock $clock, - ) {} + ) { + } public function execute(User $user): Session { diff --git a/backend/app/Auth/UseCases/Logout/Logout.php b/backend/app/Auth/UseCases/Logout/Logout.php index 31b16de..793666b 100644 --- a/backend/app/Auth/UseCases/Logout/Logout.php +++ b/backend/app/Auth/UseCases/Logout/Logout.php @@ -8,7 +8,8 @@ class Logout { public function __construct( private SessionRepository $sessionRepo, - ) {} + ) { + } public function execute(string $token): void { diff --git a/backend/app/Controllers/AuthController.php b/backend/app/Controllers/AuthController.php index 5e77602..2ab46c8 100644 --- a/backend/app/Controllers/AuthController.php +++ b/backend/app/Controllers/AuthController.php @@ -20,7 +20,8 @@ class AuthController private AuthenticateUser $authenticateUser, private CreateSession $createSession, private Logout $logout, - ) {} + ) { + } public function login( ServerRequestInterface $request, diff --git a/backend/app/Exceptions/BadRequestException.php b/backend/app/Exceptions/BadRequestException.php index b900f47..1670d31 100644 --- a/backend/app/Exceptions/BadRequestException.php +++ b/backend/app/Exceptions/BadRequestException.php @@ -4,4 +4,6 @@ namespace App\Exceptions; use DomainException; -class BadRequestException extends DomainException {} +class BadRequestException extends DomainException +{ +} diff --git a/backend/app/Exceptions/UnauthorizedException.php b/backend/app/Exceptions/UnauthorizedException.php index f5d406e..84f3f71 100644 --- a/backend/app/Exceptions/UnauthorizedException.php +++ b/backend/app/Exceptions/UnauthorizedException.php @@ -4,4 +4,6 @@ namespace App\Exceptions; use DomainException; -class UnauthorizedException extends DomainException {} +class UnauthorizedException extends DomainException +{ +} diff --git a/backend/app/Middleware/AuthMiddleware.php b/backend/app/Middleware/AuthMiddleware.php index 246f810..86174f5 100644 --- a/backend/app/Middleware/AuthMiddleware.php +++ b/backend/app/Middleware/AuthMiddleware.php @@ -17,7 +17,8 @@ class AuthMiddleware implements MiddlewareInterface public function __construct( private SessionRepository $sessionRepo, private Clock $clock, - ) {} + ) { + } public function process( ServerRequestInterface $request, diff --git a/backend/app/Shared/ValueObject/EmailAddress.php b/backend/app/Shared/ValueObject/EmailAddress.php index a744918..00ed5cf 100644 --- a/backend/app/Shared/ValueObject/EmailAddress.php +++ b/backend/app/Shared/ValueObject/EmailAddress.php @@ -18,15 +18,15 @@ final readonly class EmailAddress $trimmed = trim($email); if ($trimmed === '' || ! str_contains($trimmed, '@')) { - throw new InvalidArgumentException(self::ERROR_MESSAGE." $email"); + throw new InvalidArgumentException(self::ERROR_MESSAGE . " $email"); } [$local, $domain] = explode('@', $trimmed, 2); $this->domain = mb_strtolower($domain); - $normalized = $local.'@'.$this->domain; + $normalized = $local . '@' . $this->domain; if (filter_var($normalized, FILTER_VALIDATE_EMAIL) === false) { - throw new InvalidArgumentException(self::ERROR_MESSAGE." $email"); + throw new InvalidArgumentException(self::ERROR_MESSAGE . " $email"); } $this->normalized = $normalized; diff --git a/backend/app/User/CreateUserDto.php b/backend/app/User/CreateUserDto.php index d10b373..848d9f7 100644 --- a/backend/app/User/CreateUserDto.php +++ b/backend/app/User/CreateUserDto.php @@ -9,5 +9,6 @@ class CreateUserDto public function __construct( public EmailAddress $email, public string $passwordHash, - ) {} + ) { + } } diff --git a/backend/app/User/User.php b/backend/app/User/User.php index 3d8ed63..e73b5aa 100644 --- a/backend/app/User/User.php +++ b/backend/app/User/User.php @@ -10,7 +10,8 @@ class User private int $id, private EmailAddress $email, private string $passwordHash, - ) {} + ) { + } public function getId(): int { diff --git a/backend/tests/Fakes/FakeClock.php b/backend/tests/Fakes/FakeClock.php index f112836..7b14d8d 100644 --- a/backend/tests/Fakes/FakeClock.php +++ b/backend/tests/Fakes/FakeClock.php @@ -7,7 +7,9 @@ use DateTimeImmutable; class FakeClock implements Clock { - public function __construct(private DateTimeImmutable $currentTime) {} + public function __construct(private DateTimeImmutable $currentTime) + { + } public function now(): DateTimeImmutable { diff --git a/backend/tests/Fakes/FakePasswordHasher.php b/backend/tests/Fakes/FakePasswordHasher.php index 9e93325..507c966 100644 --- a/backend/tests/Fakes/FakePasswordHasher.php +++ b/backend/tests/Fakes/FakePasswordHasher.php @@ -8,7 +8,7 @@ class FakePasswordHasher implements PasswordHasher { public function hash(string $password): string { - return 'hashed:'.$password; + return 'hashed:' . $password; } public function verify(string $password, string $hash): bool diff --git a/backend/tests/Fakes/FakeTokenGenerator.php b/backend/tests/Fakes/FakeTokenGenerator.php index 5ea234c..e808ffd 100644 --- a/backend/tests/Fakes/FakeTokenGenerator.php +++ b/backend/tests/Fakes/FakeTokenGenerator.php @@ -9,7 +9,9 @@ class FakeTokenGenerator implements TokenGenerator { private int $callCount = 0; - public function __construct(private array $tokens) {} + public function __construct(private array $tokens) + { + } public function generate(): string { diff --git a/backend/tests/Unit/Controllers/AuthControllerTest.php b/backend/tests/Unit/Controllers/AuthControllerTest.php index 9bba649..c96e137 100644 --- a/backend/tests/Unit/Controllers/AuthControllerTest.php +++ b/backend/tests/Unit/Controllers/AuthControllerTest.php @@ -85,7 +85,7 @@ class AuthControllerTest extends TestCase $cookieHeader = $response->getHeaderLine('Set-Cookie'); $this->assertStringContainsString( - AuthMiddleware::COOKIE_NAME.'=session-token-1', + AuthMiddleware::COOKIE_NAME . '=session-token-1', $cookieHeader, ); $this->assertStringContainsString('HttpOnly', $cookieHeader); @@ -127,7 +127,7 @@ class AuthControllerTest extends TestCase $cookieHeader = $response->getHeaderLine('Set-Cookie'); $this->assertStringContainsString( - AuthMiddleware::COOKIE_NAME.'=', + AuthMiddleware::COOKIE_NAME . '=', $cookieHeader, ); } diff --git a/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-18-27.png b/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-18-27.png new file mode 100644 index 0000000..3ddfe6f Binary files /dev/null and b/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-18-27.png differ diff --git a/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-21.png b/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-21.png new file mode 100644 index 0000000..f5d8597 Binary files /dev/null and b/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-21.png differ diff --git a/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-24.png b/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-24.png new file mode 100644 index 0000000..eedee38 Binary files /dev/null and b/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-24.png differ diff --git a/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-26.png b/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-26.png new file mode 100644 index 0000000..7083595 Binary files /dev/null and b/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-26.png differ diff --git a/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-29.png b/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-29.png new file mode 100644 index 0000000..8440e30 Binary files /dev/null and b/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-29.png differ diff --git a/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-34.png b/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-34.png new file mode 100644 index 0000000..5b6ac51 Binary files /dev/null and b/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-34.png differ diff --git a/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-37.png b/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-37.png new file mode 100644 index 0000000..5950082 Binary files /dev/null and b/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-37.png differ diff --git a/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-44.png b/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-44.png new file mode 100644 index 0000000..fd216e5 Binary files /dev/null and b/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-44.png differ diff --git a/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-47.png b/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-47.png new file mode 100644 index 0000000..52b0edd Binary files /dev/null and b/frontend/rabbi_gerzi/public/assets/Screenshot from 2026-05-16 21-22-47.png differ