feat: set session token, improved paths
This commit is contained in:
parent
89422726bf
commit
02af66b585
@ -22,7 +22,7 @@ class AuthService {
|
||||
|
||||
/// Route to generate a token
|
||||
@Route.post('/login')
|
||||
Future<Response> generateToken(Request request) async {
|
||||
Future<Response> 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<Response> revokeToken(Request request) async {
|
||||
@Route.post('/logout')
|
||||
Future<Response> logout(Request request) async {
|
||||
return requestToJson(request)
|
||||
.flatMap(validateJsonKeys(['token']))
|
||||
.flatMap((json) => decodeJson(json, TokenRequestDTO.fromJson))
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user