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 to generate a token
|
||||||
@Route.post('/login')
|
@Route.post('/login')
|
||||||
Future<Response> generateToken(Request request) async {
|
Future<Response> login(Request request) async {
|
||||||
return requestToJson(request)
|
return requestToJson(request)
|
||||||
.flatMap(validateJsonKeys(['email', 'password']))
|
.flatMap(validateJsonKeys(['email', 'password']))
|
||||||
.flatMap((json) => decodeJson(json, LoginRequestDTO.fromJson))
|
.flatMap((json) => decodeJson(json, LoginRequestDTO.fromJson))
|
||||||
@ -59,8 +59,8 @@ class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Route to revoke a token
|
/// Route to revoke a token
|
||||||
@Route.post('/revoke')
|
@Route.post('/logout')
|
||||||
Future<Response> revokeToken(Request request) async {
|
Future<Response> logout(Request request) async {
|
||||||
return requestToJson(request)
|
return requestToJson(request)
|
||||||
.flatMap(validateJsonKeys(['token']))
|
.flatMap(validateJsonKeys(['token']))
|
||||||
.flatMap((json) => decodeJson(json, TokenRequestDTO.fromJson))
|
.flatMap((json) => decodeJson(json, TokenRequestDTO.fromJson))
|
||||||
|
@ -11,7 +11,7 @@ Router _$AuthServiceRouter(AuthService service) {
|
|||||||
router.add(
|
router.add(
|
||||||
'POST',
|
'POST',
|
||||||
r'/login',
|
r'/login',
|
||||||
service.generateToken,
|
service.login,
|
||||||
);
|
);
|
||||||
router.add(
|
router.add(
|
||||||
'POST',
|
'POST',
|
||||||
@ -20,8 +20,8 @@ Router _$AuthServiceRouter(AuthService service) {
|
|||||||
);
|
);
|
||||||
router.add(
|
router.add(
|
||||||
'POST',
|
'POST',
|
||||||
r'/revoke',
|
r'/logout',
|
||||||
service.revokeToken,
|
service.logout,
|
||||||
);
|
);
|
||||||
return router;
|
return router;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"actatempus_backend/internal/application/services/dto"
|
"actatempus_backend/internal/application/services/dto"
|
||||||
|
mappers "actatempus_backend/internal/application/services/mapper"
|
||||||
"actatempus_backend/internal/domain/app_error"
|
"actatempus_backend/internal/domain/app_error"
|
||||||
"actatempus_backend/internal/domain/entities"
|
"actatempus_backend/internal/domain/entities"
|
||||||
"actatempus_backend/internal/domain/repository"
|
"actatempus_backend/internal/domain/repository"
|
||||||
@ -32,7 +33,7 @@ func NewAuthService(authRepo repository.AuthRepository,
|
|||||||
func (s *AuthService) RegisterRoutes(router *gin.RouterGroup) {
|
func (s *AuthService) RegisterRoutes(router *gin.RouterGroup) {
|
||||||
router.POST("/login", s.Login)
|
router.POST("/login", s.Login)
|
||||||
router.POST("/validate", s.Validate)
|
router.POST("/validate", s.Validate)
|
||||||
router.POST("/revoke", s.Revoke)
|
router.POST("/logout", s.Logout)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Login handles user login and token generation.
|
// Login handles user login and token generation.
|
||||||
@ -47,24 +48,14 @@ func (s *AuthService) Login(c *gin.Context) {
|
|||||||
loginRequest.Email,
|
loginRequest.Email,
|
||||||
s.userRepository.FindByEmail(c.Request.Context()),
|
s.userRepository.FindByEmail(c.Request.Context()),
|
||||||
E.Chain[error](
|
E.Chain[error](
|
||||||
func(user entities.User) E.Either[error, entities.User] {
|
validatePassword(loginRequest.Password),
|
||||||
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)
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
E.Chain(func(user entities.User) E.Either[error, dto.TokenResponseDTO] {
|
E.Chain(func(user entities.User) E.Either[error, dto.TokenResponseDTO] {
|
||||||
return F.Pipe2(
|
return F.Pipe3(
|
||||||
user.ID,
|
user.ID,
|
||||||
s.authRepository.GenerateToken(c.Request.Context()),
|
s.authRepository.GenerateToken(c.Request.Context()),
|
||||||
E.Map[error](func(token string) dto.TokenResponseDTO {
|
E.Map[error](setSessionTokenCookie(c, user)),
|
||||||
return dto.TokenResponseDTO{
|
E.Map[error](mappers.ToTokenDTO(user)),
|
||||||
Token: token,
|
|
||||||
UserID: user.ID,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
E.Fold(
|
E.Fold(
|
||||||
@ -97,14 +88,16 @@ func (s *AuthService) Validate(c *gin.Context) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Revoke handles token revocation.
|
// Logout and token revocation.
|
||||||
func (s *AuthService) Revoke(c *gin.Context) {
|
func (s *AuthService) Logout(c *gin.Context) {
|
||||||
var tokenRequest dto.TokenRequestDTO
|
var tokenRequest dto.TokenRequestDTO
|
||||||
if err := c.ShouldBindJSON(&tokenRequest); err != nil {
|
if err := c.ShouldBindJSON(&tokenRequest); err != nil {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteSessionTokenCookie(c)
|
||||||
|
|
||||||
F.Pipe2(
|
F.Pipe2(
|
||||||
s.authRepository.RevokeToken(c.Request.Context())(tokenRequest.Token),
|
s.authRepository.RevokeToken(c.Request.Context())(tokenRequest.Token),
|
||||||
E.Map[error](func(userID string) gin.H {
|
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