diff --git a/backend-dart/lib/application/service/auth_service.dart b/backend-dart/lib/application/service/auth_service.dart index 89f4fbc..36996e7 100644 --- a/backend-dart/lib/application/service/auth_service.dart +++ b/backend-dart/lib/application/service/auth_service.dart @@ -22,7 +22,7 @@ class AuthService { /// Route to generate a token @Route.post('/login') - Future generateToken(Request request) async { + Future login(Request request) async { return requestToJson(request) .flatMap(validateJsonKeys(['email', 'password'])) .flatMap((json) => decodeJson(json, LoginRequestDTO.fromJson)) @@ -59,8 +59,8 @@ class AuthService { } /// Route to revoke a token - @Route.post('/revoke') - Future revokeToken(Request request) async { + @Route.post('/logout') + Future logout(Request request) async { return requestToJson(request) .flatMap(validateJsonKeys(['token'])) .flatMap((json) => decodeJson(json, TokenRequestDTO.fromJson)) diff --git a/backend-dart/lib/application/service/auth_service.g.dart b/backend-dart/lib/application/service/auth_service.g.dart index 33b4e91..773d73e 100644 --- a/backend-dart/lib/application/service/auth_service.g.dart +++ b/backend-dart/lib/application/service/auth_service.g.dart @@ -11,7 +11,7 @@ Router _$AuthServiceRouter(AuthService service) { router.add( 'POST', r'/login', - service.generateToken, + service.login, ); router.add( 'POST', @@ -20,8 +20,8 @@ Router _$AuthServiceRouter(AuthService service) { ); router.add( 'POST', - r'/revoke', - service.revokeToken, + r'/logout', + service.logout, ); return router; } diff --git a/backend-go/internal/application/services/auth_service.go b/backend-go/internal/application/services/auth_service.go index e46f746..9be41a3 100644 --- a/backend-go/internal/application/services/auth_service.go +++ b/backend-go/internal/application/services/auth_service.go @@ -2,6 +2,7 @@ package services import ( "actatempus_backend/internal/application/services/dto" + mappers "actatempus_backend/internal/application/services/mapper" "actatempus_backend/internal/domain/app_error" "actatempus_backend/internal/domain/entities" "actatempus_backend/internal/domain/repository" @@ -32,7 +33,7 @@ func NewAuthService(authRepo repository.AuthRepository, func (s *AuthService) RegisterRoutes(router *gin.RouterGroup) { router.POST("/login", s.Login) router.POST("/validate", s.Validate) - router.POST("/revoke", s.Revoke) + router.POST("/logout", s.Logout) } // Login handles user login and token generation. @@ -47,24 +48,14 @@ func (s *AuthService) Login(c *gin.Context) { loginRequest.Email, s.userRepository.FindByEmail(c.Request.Context()), E.Chain[error]( - func(user entities.User) E.Either[error, entities.User] { - hashedPassword := data.GenerateSecureHash(loginRequest.Password) - if user.Password != hashedPassword { - return E.Left[entities.User, error](app_error.NewAuthError("Invalid password")) - } - return E.Right[error](user) - }, + validatePassword(loginRequest.Password), ), E.Chain(func(user entities.User) E.Either[error, dto.TokenResponseDTO] { - return F.Pipe2( + return F.Pipe3( user.ID, s.authRepository.GenerateToken(c.Request.Context()), - E.Map[error](func(token string) dto.TokenResponseDTO { - return dto.TokenResponseDTO{ - Token: token, - UserID: user.ID, - } - }), + E.Map[error](setSessionTokenCookie(c, user)), + E.Map[error](mappers.ToTokenDTO(user)), ) }), E.Fold( @@ -97,14 +88,16 @@ func (s *AuthService) Validate(c *gin.Context) { ) } -// Revoke handles token revocation. -func (s *AuthService) Revoke(c *gin.Context) { +// Logout and token revocation. +func (s *AuthService) Logout(c *gin.Context) { var tokenRequest dto.TokenRequestDTO if err := c.ShouldBindJSON(&tokenRequest); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } + deleteSessionTokenCookie(c) + F.Pipe2( s.authRepository.RevokeToken(c.Request.Context())(tokenRequest.Token), E.Map[error](func(userID string) gin.H { @@ -116,3 +109,26 @@ func (s *AuthService) Revoke(c *gin.Context) { ), ) } + +func setSessionTokenCookie(c *gin.Context, user entities.User) func(token string) string { + return func(token string) string { + c.SetCookie("session_token", token, 3600, "/", "localhost", false, true) + c.SetCookie("user_id", user.ID, 3600, "/", "localhost", false, true) + return token + } +} + +func deleteSessionTokenCookie(c *gin.Context) { + c.SetCookie("session_token", "", -1, "/", "localhost", false, true) + c.SetCookie("user_id", "", -1, "/", "localhost", false, true) +} + +func validatePassword(password string) func(user entities.User) E.Either[error, entities.User] { + return func(user entities.User) E.Either[error, entities.User] { + hashedPassword := data.GenerateSecureHash(password) + if user.Password != hashedPassword { + return E.Left[entities.User, error](app_error.NewAuthError("Invalid password")) + } + return E.Right[error](user) + } +} diff --git a/backend-go/internal/application/services/mapper/token_dto_mapper.go b/backend-go/internal/application/services/mapper/token_dto_mapper.go new file mode 100644 index 0000000..d2a58fb --- /dev/null +++ b/backend-go/internal/application/services/mapper/token_dto_mapper.go @@ -0,0 +1,15 @@ +package mappers + +import ( + "actatempus_backend/internal/application/services/dto" + "actatempus_backend/internal/domain/entities" +) + +func ToTokenDTO(user entities.User) func(string) dto.TokenResponseDTO { + return func(token string) dto.TokenResponseDTO { + return dto.TokenResponseDTO{ + Token: token, + UserID: user.ID, + } + } +}