package api import ( "database/sql" "net/http" "time" db "git.nochill.in/nochill/naice_pos/db/sqlc" "git.nochill.in/nochill/naice_pos/util" "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/lib/pq" ) type createUserMerchantRequest struct { Email string `json:"email" binding:"required,email"` Fullname string `json:"fullname" binding:"required,alphanum"` Password string `json:"password" binding:"required"` OutletName string `json:"outlet_name" binding:"required"` } type userMerchantResponse struct { ID uuid.UUID `json:"id"` IndexID int64 `json:"index_id"` Email string `json:"email"` Fullname string `json:"fullname"` CreatedAt sql.NullTime `json:"created_at"` UpdatedAt sql.NullTime `json:"updated_at"` OutletID uuid.UUID `json:"outlet_id"` OutletIndexID int64 `json:"outlet_index_id"` OutletName string `json:"outlet_name"` OutletOwnerID uuid.UUID `json:"outlet_owner_id"` } func newUserMerchantResponse(user db.GetUserByEmailRow) userMerchantResponse { return userMerchantResponse{ ID: user.ID, IndexID: user.IndexID, Email: user.Email, Fullname: user.Fullname, CreatedAt: sql.NullTime{Valid: true, Time: user.CreatedAt.Time}, UpdatedAt: sql.NullTime{Valid: true, Time: user.UpdatedAt.Time}, OutletID: user.ID_2, OutletIndexID: user.IndexID_2, OutletName: user.Name, OutletOwnerID: user.OwnerID, } } func (server *Server) createUserMerchant(ctx *gin.Context) { var req createUserMerchantRequest if err := ctx.ShouldBindJSON(&req); err != nil { ctx.JSON(http.StatusBadRequest, errorResponse(err, "")) return } hashedPassword, err := util.HashPassword(req.Password) if err != nil { ctx.JSON(http.StatusInternalServerError, errorResponse(err, "")) return } arg := db.UserMerchantTxParams{ Email: req.Email, Fullname: req.Fullname, Password: hashedPassword, OutletName: req.OutletName, } user, err := server.store.CreateUserMerchantTx(ctx, arg) if err != nil { if pqErr, ok := err.(*pq.Error); ok { switch pqErr.Code.Name() { case "foreign_key_violation", "unique_violation": ctx.JSON(http.StatusConflict, errorResponse(err, "")) return } } ctx.JSON(http.StatusInternalServerError, errorResponse(err, "")) return } res := userMerchantResponse{ ID: user.OwnerProfile.ID, IndexID: user.OwnerProfile.IndexID, Email: user.OwnerProfile.Email, Fullname: user.OwnerProfile.Fullname, CreatedAt: sql.NullTime{Valid: true, Time: user.OwnerProfile.CreatedAt.Time}, UpdatedAt: sql.NullTime{Valid: true, Time: user.OwnerProfile.UpdatedAt.Time}, OutletID: user.OutletProfile.ID, OutletIndexID: user.OutletProfile.IndexID, OutletName: user.OutletProfile.Name, OutletOwnerID: user.OutletProfile.OwnerID, } ctx.JSON(http.StatusOK, res) } type userLoginRequest struct { Email string `json:"email" binding:"required,email"` Password string `json:"password" binding:"required"` } type userTokenResponse struct { SessionID uuid.UUID `json:"session_id"` AccesToken string `json:"access_token"` AccessTokenExpiresAt time.Time `json:"access_token_expires_at"` RefreshToken string `json:"refresh_token"` RefreshTokenExpiresAt time.Time `json:"refresh_token_expires_at"` } type userLoginResponse struct { UserTokenResponse userTokenResponse `json:"user_token"` UserMerchantResponse userMerchantResponse `json:"user"` } func (server *Server) loginUser(ctx *gin.Context) { var req userLoginRequest if err := ctx.ShouldBindJSON(&req); err != nil { ctx.JSON(http.StatusBadRequest, errorResponse(err, "")) return } user, err := server.store.GetUserByEmail(ctx, req.Email) if err != nil { if err == sql.ErrNoRows { ctx.JSON(http.StatusNotFound, errorResponse(err, "")) return } ctx.JSON(http.StatusInternalServerError, errorResponse(err, "")) return } err = util.CheckPassword(req.Password, user.Password) if err != nil { ctx.JSON(http.StatusUnauthorized, errorResponse(err, "")) return } accessToken, accessPayload, err := server.tokenMaker.CreateToken( user.Email, user.ID_2.String(), server.config.TokenDuration, ) if err != nil { ctx.JSON(http.StatusInternalServerError, errorResponse(err, "")) return } refreshToken, refreshTokenPayload, err := server.tokenMaker.CreateToken( user.Email, user.ID_2.String(), server.config.RefreshTokenDuration, ) session, err := server.store.CreateSession(ctx, db.CreateSessionParams{ ID: refreshTokenPayload.ID, Email: user.Email, RefreshToken: refreshToken, UserAgent: ctx.Request.UserAgent(), ClientIp: ctx.ClientIP(), IsBlocked: false, ExpiresAt: refreshTokenPayload.ExpiredAt, }) if err != nil { ctx.JSON(http.StatusInternalServerError, errorResponse(err, "")) return } tokenResponse := userTokenResponse{ SessionID: session.ID, AccesToken: accessToken, AccessTokenExpiresAt: accessPayload.ExpiredAt, RefreshToken: refreshToken, RefreshTokenExpiresAt: refreshTokenPayload.ExpiredAt, } res := BaseApiRespond("succes", userLoginResponse{ UserTokenResponse: tokenResponse, UserMerchantResponse: newUserMerchantResponse(user), }) ctx.JSON(http.StatusOK, res) }