Spaces:
Running
Running
| package controllers | |
| import ( | |
| "net/http" | |
| "strings" | |
| "whatsapp-backend/models/dto" | |
| http_error "whatsapp-backend/models/error" | |
| "whatsapp-backend/services" | |
| "whatsapp-backend/utils" | |
| "github.com/gin-gonic/gin" | |
| "github.com/google/uuid" | |
| ) | |
| type AuthController interface { | |
| Register(ctx *gin.Context) | |
| Login(ctx *gin.Context) | |
| Logout(ctx *gin.Context) | |
| RefreshToken(ctx *gin.Context) | |
| Me(ctx *gin.Context) | |
| AssignRole(ctx *gin.Context) | |
| RegisterEnabled(ctx *gin.Context) | |
| } | |
| type authController struct { | |
| authService services.AuthService | |
| } | |
| func NewAuthController(authService services.AuthService) AuthController { | |
| return &authController{authService: authService} | |
| } | |
| // Register godoc | |
| // @Summary Register a new user | |
| // @Description Register a new user with the provided details | |
| // @Tags auth | |
| // @Accept json | |
| // @Produce json | |
| // @Param request body dto.RegisterRequest true "Register Request" | |
| // @Success 200 {object} dto.AuthResponse | |
| // @Failure 400 {object} dto.ErrorResponse | |
| // @Router /auth/register [post] | |
| func (c *authController) Register(ctx *gin.Context) { | |
| var req dto.RegisterRequest | |
| if err := ctx.ShouldBindJSON(&req); err != nil { | |
| utils.SendResponse[any, any](ctx, nil, nil, err) | |
| return | |
| } | |
| resp, err := c.authService.Register(req) | |
| if err != nil { | |
| utils.SendResponse[any, any](ctx, nil, nil, err) | |
| return | |
| } | |
| ctx.SetSameSite(http.SameSiteNoneMode) | |
| ctx.SetCookie("RefreshToken", resp.RefreshToken, 3600*24*7, "/", "", true, true) | |
| utils.SendResponse[dto.AuthResponse, any](ctx, nil, *resp, nil) | |
| } | |
| // Login godoc | |
| // @Summary Login a user | |
| // @Description Login a user with credentials | |
| // @Tags auth | |
| // @Accept json | |
| // @Produce json | |
| // @Param request body dto.LoginRequest true "Login Request" | |
| // @Success 200 {object} dto.AuthResponse | |
| // @Failure 400 {object} dto.ErrorResponse | |
| // @Router /auth/login [post] | |
| func (c *authController) Login(ctx *gin.Context) { | |
| var req dto.LoginRequest | |
| if err := ctx.ShouldBindJSON(&req); err != nil { | |
| utils.SendResponse[any, any](ctx, nil, nil, err) | |
| return | |
| } | |
| resp, err := c.authService.Login(req) | |
| if err != nil { | |
| utils.SendResponse[any, any](ctx, nil, nil, err) | |
| return | |
| } | |
| ctx.SetSameSite(http.SameSiteNoneMode) | |
| ctx.SetCookie("RefreshToken", resp.RefreshToken, 3600*24*7, "/", "", true, true) | |
| utils.SendResponse[dto.AuthResponse, any](ctx, nil, *resp, nil) | |
| } | |
| // Logout godoc | |
| // @Summary Logout a user | |
| // @Description Logout the current user | |
| // @Tags auth | |
| // @Security BearerAuth | |
| // @Success 200 | |
| // @Router /auth/logout [post] | |
| func (c *authController) Logout(ctx *gin.Context) { | |
| tokenString := "" | |
| authHeader := ctx.GetHeader("Authorization") | |
| if authHeader != "" { | |
| tokenString = strings.Replace(authHeader, "Bearer", "", 1) | |
| } else { | |
| cookie, err := ctx.Cookie("Authorization") | |
| if err == nil { | |
| tokenString = cookie | |
| } | |
| } | |
| refreshToken, _ := ctx.Cookie("RefreshToken") | |
| if tokenString != "" || refreshToken != "" { | |
| _ = c.authService.Logout(tokenString, refreshToken) | |
| } | |
| ctx.SetSameSite(http.SameSiteNoneMode) | |
| ctx.SetCookie("RefreshToken", "", -1, "/", "", true, true) | |
| utils.SendResponse[dto.LogoutResponse, any](ctx, nil, dto.LogoutResponse{ | |
| SuccessMsg: "Logout successful", | |
| }, nil) | |
| } | |
| // RefreshToken godoc | |
| // @Summary Refresh access token | |
| // @Description Refresh the access token using the refresh token cookie | |
| // @Tags auth | |
| // @Security BearerAuth | |
| // @Success 200 {object} dto.AuthResponse | |
| // @Failure 401 {object} dto.ErrorResponse | |
| // @Router /auth/refresh [post] | |
| func (c *authController) RefreshToken(ctx *gin.Context) { | |
| refreshToken, err := ctx.Cookie("RefreshToken") | |
| if err != nil || refreshToken == "" { | |
| utils.SendResponse[any, any](ctx, nil, nil, http_error.UNAUTHORIZED) | |
| return | |
| } | |
| newAccessToken, newRefreshToken, err := c.authService.RefreshToken(refreshToken) | |
| if err != nil { | |
| ctx.SetCookie("RefreshToken", "", -1, "/", "", true, true) | |
| utils.SendResponse[any, any](ctx, nil, nil, err) | |
| return | |
| } | |
| // Only set refresh token cookie if a new one was issued | |
| if newRefreshToken != "" { | |
| ctx.SetSameSite(http.SameSiteNoneMode) | |
| ctx.SetCookie("RefreshToken", newRefreshToken, 3600*24*7, "/", "", true, true) | |
| } | |
| utils.SendResponse[dto.AuthResponse, any](ctx, nil, dto.AuthResponse{ | |
| AccessToken: newAccessToken, | |
| }, nil) | |
| } | |
| // Me godoc | |
| // @Summary Get current user profile | |
| // @Description Get the profile of the currently logged-in user | |
| // @Tags auth | |
| // @Security BearerAuth | |
| // @Success 200 {object} dto.MeResponse | |
| // @Failure 401 {object} dto.ErrorResponse | |
| // @Router /auth/me [get] | |
| func (c *authController) Me(ctx *gin.Context) { | |
| userId, exists := ctx.Get("user_id") | |
| if !exists { | |
| utils.SendResponse[any, any](ctx, nil, nil, nil) | |
| return | |
| } | |
| resp, err := c.authService.GetMe(userId.(uuid.UUID)) | |
| if err != nil { | |
| utils.SendResponse[any, any](ctx, nil, nil, err) | |
| return | |
| } | |
| utils.SendResponse[dto.MeResponse, any](ctx, nil, *resp, nil) | |
| } | |
| // AssignRole godoc | |
| // @Summary Assign Role (SuperAdmin) | |
| // @Description Assign a role to a user | |
| // @Tags auth | |
| // @Security BearerAuth | |
| // @Accept json | |
| // @Produce json | |
| // @Param request body dto.AssignRoleRequest true "Assign Role Request" | |
| // @Success 200 | |
| // @Failure 400 {object} dto.ErrorResponse | |
| // @Router /auth/assign [post] | |
| func (c *authController) AssignRole(ctx *gin.Context) { | |
| var req dto.AssignRoleRequest | |
| if err := ctx.ShouldBindJSON(&req); err != nil { | |
| utils.SendResponse[any, any](ctx, nil, nil, err) | |
| return | |
| } | |
| if err := c.authService.AssignRole(req.UserID, req.Role); err != nil { | |
| utils.SendResponse[any, any](ctx, nil, nil, err) | |
| return | |
| } | |
| utils.SendResponse[any, any](ctx, nil, nil, nil) | |
| } | |
| // RegisterEnabled godoc | |
| // @Summary Check if registration is enabled | |
| // @Description Check if user registration is enabled | |
| // @Tags auth | |
| // @Security BearerAuth | |
| // @Success 200 {object} dto.RegisterEnabledResponse | |
| // @Router /auth/register_enabled [get] | |
| func (c *authController) RegisterEnabled(ctx *gin.Context) { | |
| utils.SendResponse[dto.RegisterEnabledResponse, any](ctx, nil, dto.RegisterEnabledResponse{ | |
| Register: c.authService.IsRegisterEnabled(), | |
| }, nil) | |
| } | |