This commit is contained in:
@@ -432,3 +432,40 @@ func (h *AuthController) GoogleCallback(c fiber.Ctx) error {
|
|||||||
|
|
||||||
return c.Redirect().To(redirectURL)
|
return c.Redirect().To(redirectURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *AuthController) Logout(c fiber.Ctx) error {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
userId := c.Locals("uid").(string)
|
||||||
|
|
||||||
|
err := h.service.Logout(ctx, userId)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(response.CommonResponse{
|
||||||
|
Status: false,
|
||||||
|
Message: err.Error(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Cookie(&fiber.Cookie{
|
||||||
|
Name: "access_token",
|
||||||
|
Value: "",
|
||||||
|
Expires: time.Now().Add(-time.Hour),
|
||||||
|
HTTPOnly: true,
|
||||||
|
Secure: true,
|
||||||
|
Path: "/",
|
||||||
|
})
|
||||||
|
|
||||||
|
c.Cookie(&fiber.Cookie{
|
||||||
|
Name: "refresh_token",
|
||||||
|
Value: "",
|
||||||
|
Expires: time.Now().Add(-time.Hour),
|
||||||
|
HTTPOnly: true,
|
||||||
|
Secure: true,
|
||||||
|
Path: "/",
|
||||||
|
})
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).JSON(response.CommonResponse{
|
||||||
|
Status: true,
|
||||||
|
Message: "Logged out successfully",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,4 +18,5 @@ func AuthRoutes(app *fiber.App, controller *controllers.AuthController, userRepo
|
|||||||
route.Post("/forgot-password", controller.ForgotPassword)
|
route.Post("/forgot-password", controller.ForgotPassword)
|
||||||
route.Get("/google/login", controller.GoogleLogin)
|
route.Get("/google/login", controller.GoogleLogin)
|
||||||
route.Get("/google/callback", controller.GoogleCallback)
|
route.Get("/google/callback", controller.GoogleCallback)
|
||||||
|
route.Post("/logout", middlewares.JwtAccess(userRepo), controller.Logout)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import (
|
|||||||
type AuthService interface {
|
type AuthService interface {
|
||||||
Signin(ctx context.Context, dto *request.SignInDto) (*response.AuthResponse, error)
|
Signin(ctx context.Context, dto *request.SignInDto) (*response.AuthResponse, error)
|
||||||
Signup(ctx context.Context, dto *request.SignUpDto) (*response.AuthResponse, error)
|
Signup(ctx context.Context, dto *request.SignUpDto) (*response.AuthResponse, error)
|
||||||
|
Logout(ctx context.Context, userId string) error
|
||||||
ForgotPassword(ctx context.Context, dto *request.ForgotPasswordDto) error
|
ForgotPassword(ctx context.Context, dto *request.ForgotPasswordDto) error
|
||||||
VerifyToken(ctx context.Context, dto *request.VerifyTokenDto) (*response.VerifyTokenResponse, error)
|
VerifyToken(ctx context.Context, dto *request.VerifyTokenDto) (*response.VerifyTokenResponse, error)
|
||||||
CreateToken(ctx context.Context, dto *request.CreateTokenDto) error
|
CreateToken(ctx context.Context, dto *request.CreateTokenDto) error
|
||||||
@@ -170,6 +171,38 @@ func (a *authService) Signin(ctx context.Context, dto *request.SignInDto) (*resp
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (a *authService) Logout(ctx context.Context, userId string) error {
|
||||||
|
pgID, err := convert.StringToUUID(userId)
|
||||||
|
if err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
user , err := a.userRepo.GetByID(ctx, pgID)
|
||||||
|
if err != nil || user == nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Invalid user data")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = a.userRepo.UpdateTokenVersion(ctx, sqlc.UpdateTokenVersionParams{
|
||||||
|
ID: pgID,
|
||||||
|
TokenVersion: user.TokenVersion + 1,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
err = a.userRepo.UpdateRefreshToken(ctx, sqlc.UpdateUserRefreshTokenParams{
|
||||||
|
ID: pgID,
|
||||||
|
RefreshToken: pgtype.Text{
|
||||||
|
String: "",
|
||||||
|
Valid: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (a *authService) RefreshToken(ctx context.Context, id string) (*response.AuthResponse, error) {
|
func (a *authService) RefreshToken(ctx context.Context, id string) (*response.AuthResponse, error) {
|
||||||
var pgID pgtype.UUID
|
var pgID pgtype.UUID
|
||||||
err := pgID.Scan(id)
|
err := pgID.Scan(id)
|
||||||
|
|||||||
@@ -210,8 +210,8 @@ func (u *userService) RestoreUser(ctx context.Context, userId string) (*response
|
|||||||
|
|
||||||
func (u *userService) SearchUser(ctx context.Context, dto *request.SearchUserDto) (*response.PaginatedResponse, error) {
|
func (u *userService) SearchUser(ctx context.Context, dto *request.SearchUserDto) (*response.PaginatedResponse, error) {
|
||||||
arg := sqlc.SearchUsersParams{
|
arg := sqlc.SearchUsersParams{
|
||||||
Limit: int32(dto.Limit + 1),
|
Limit: int32(dto.Limit + 1),
|
||||||
}
|
}
|
||||||
|
|
||||||
if dto.Sort != "" {
|
if dto.Sort != "" {
|
||||||
arg.Sort = pgtype.Text{String: dto.Sort, Valid: true}
|
arg.Sort = pgtype.Text{String: dto.Sort, Valid: true}
|
||||||
@@ -225,64 +225,64 @@ func (u *userService) SearchUser(ctx context.Context, dto *request.SearchUserDto
|
|||||||
arg.Order = pgtype.Text{String: "asc", Valid: true}
|
arg.Order = pgtype.Text{String: "asc", Valid: true}
|
||||||
}
|
}
|
||||||
|
|
||||||
if dto.Cursor != "" {
|
if dto.Cursor != "" {
|
||||||
pgID, err := convert.StringToUUID(dto.Cursor)
|
pgID, err := convert.StringToUUID(dto.Cursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid cursor format")
|
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid cursor format")
|
||||||
}
|
}
|
||||||
arg.Cursor = pgID
|
arg.Cursor = pgID
|
||||||
}
|
}
|
||||||
|
|
||||||
if dto.Search != "" {
|
if dto.Search != "" {
|
||||||
pgID, err := convert.StringToUUID(dto.Search)
|
pgID, err := convert.StringToUUID(dto.Search)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
arg.SearchID = pgID
|
arg.SearchID = pgID
|
||||||
} else {
|
} else {
|
||||||
arg.SearchText = pgtype.Text{String: dto.Search, Valid: true}
|
arg.SearchText = pgtype.Text{String: dto.Search, Valid: true}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if dto.IsDeleted != nil {
|
if dto.IsDeleted != nil {
|
||||||
arg.IsDeleted = pgtype.Bool{Bool: *dto.IsDeleted, Valid: true}
|
arg.IsDeleted = pgtype.Bool{Bool: *dto.IsDeleted, Valid: true}
|
||||||
}
|
}
|
||||||
if len(dto.RoleIDs) > 0 {
|
if len(dto.RoleIDs) > 0 {
|
||||||
var pgRoleIDs []pgtype.UUID
|
var pgRoleIDs []pgtype.UUID
|
||||||
for _, idStr := range dto.RoleIDs {
|
for _, idStr := range dto.RoleIDs {
|
||||||
pgID, err := convert.StringToUUID(idStr)
|
pgID, err := convert.StringToUUID(idStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pgRoleIDs = append(pgRoleIDs, pgID)
|
pgRoleIDs = append(pgRoleIDs, pgID)
|
||||||
}
|
}
|
||||||
arg.RoleIds = pgRoleIDs
|
arg.RoleIds = pgRoleIDs
|
||||||
}
|
}
|
||||||
|
|
||||||
rows, err := u.userRepo.Search(ctx, arg)
|
rows, err := u.userRepo.Search(ctx, arg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
hasMore := false
|
hasMore := false
|
||||||
var nextCursor string
|
var nextCursor string
|
||||||
|
|
||||||
if len(rows) > dto.Limit {
|
if len(rows) > dto.Limit {
|
||||||
hasMore = true
|
hasMore = true
|
||||||
nextCursor = rows[dto.Limit-1].ID
|
nextCursor = rows[dto.Limit-1].ID
|
||||||
rows = rows[:dto.Limit]
|
rows = rows[:dto.Limit]
|
||||||
}
|
}
|
||||||
|
|
||||||
users := models.UsersEntityToResponse(rows)
|
users := models.UsersEntityToResponse(rows)
|
||||||
|
|
||||||
res := &response.PaginatedResponse{
|
res := &response.PaginatedResponse{
|
||||||
Data: users,
|
Data: users,
|
||||||
Status: true,
|
Status: true,
|
||||||
Message: "",
|
Message: "",
|
||||||
}
|
}
|
||||||
|
|
||||||
res.Pagination.HasMore = hasMore
|
res.Pagination.HasMore = hasMore
|
||||||
res.Pagination.NextCursor = nextCursor
|
res.Pagination.NextCursor = nextCursor
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *userService) GetUserByID(ctx context.Context, userId string) (*response.UserResponse, error) {
|
func (u *userService) GetUserByID(ctx context.Context, userId string) (*response.UserResponse, error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user