Spaces:
Running
Running
File size: 6,346 Bytes
44c4b7e ca18868 44c4b7e ca18868 44c4b7e ca18868 44c4b7e ca18868 44c4b7e ca18868 2a792a5 bd43fe2 44c4b7e c099d87 44c4b7e f5271f7 b0b934b 44c4b7e c099d87 44c4b7e f5271f7 b0b934b ca18868 44c4b7e ca18868 c099d87 2a792a5 c099d87 ca18868 28b1128 ca18868 f5271f7 b0b934b f7fe55b ca18868 c099d87 2a792a5 c099d87 ca18868 b0b934b ca18868 f7fe55b f5271f7 b0b934b f7fe55b ca18868 f7fe55b ca18868 c099d87 ca18868 2a792a5 bd43fe2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
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)
}
|