diff --git a/bruno/register user.yml b/bruno/login user.yml similarity index 85% rename from bruno/register user.yml rename to bruno/login user.yml index d4ccb71..2996080 100644 --- a/bruno/register user.yml +++ b/bruno/login user.yml @@ -1,11 +1,11 @@ info: - name: register user + name: login user type: http seq: 1 http: method: POST - url: "{{host}}/api/auth/register" + url: "{{host}}/api/v1/auth/login" body: type: json data: |- diff --git a/cmd/api/main.go b/cmd/api/main.go index edf5219..529cecc 100644 --- a/cmd/api/main.go +++ b/cmd/api/main.go @@ -3,9 +3,12 @@ package main import ( "git.kanopo.dev/rhythm/rhythm-backend/internal/config" "git.kanopo.dev/rhythm/rhythm-backend/internal/db" + usersdb "git.kanopo.dev/rhythm/rhythm-backend/internal/db/users" "git.kanopo.dev/rhythm/rhythm-backend/internal/http" + "git.kanopo.dev/rhythm/rhythm-backend/internal/http/api/auth" "git.kanopo.dev/rhythm/rhythm-backend/internal/http/api/health" "git.kanopo.dev/rhythm/rhythm-backend/internal/logger" + "git.kanopo.dev/rhythm/rhythm-backend/internal/service/users" "go.uber.org/fx" "go.uber.org/fx/fxevent" "go.uber.org/zap" @@ -14,11 +17,14 @@ import ( func main() { fx.New( fx.Provide( - config.Provide, - logger.ProvideLogger, - db.ProvidePool, - http.NewServer, - health.NewHandler, + config.Provide, //config + logger.ProvideLogger, //logger + db.ProvidePool, // pool provider + usersdb.New, // generated code for sqlc + users.NewService, // service + http.NewServer, // http server + health.NewHandler, // http handler + auth.NewHandler, //http handler ), fx.Invoke( http.GlueRoutes, diff --git a/internal/http/api/auth/handler.go b/internal/http/api/auth/handler.go new file mode 100644 index 0000000..7c67a7e --- /dev/null +++ b/internal/http/api/auth/handler.go @@ -0,0 +1,48 @@ +package auth + +import ( + "net/http" + "time" + + "github.com/gin-gonic/gin" + "go.uber.org/zap" +) + +type Handler struct { + log *zap.SugaredLogger +} + +func NewHandler(log *zap.SugaredLogger) *Handler { + return &Handler{ + log: log, + } +} + +func (h *Handler) RegisterRoutes(rg *gin.RouterGroup) { + rg.POST("/login", h.Login) +} + +func setRefreshTokenCookie(c *gin.Context, token string) { + maxAge := time.Hour * 24 * 7 + c.SetCookie( + "refresh_token", // name + token, // value + int(maxAge), // maxAge (seconds, 7 days) + "/", // path + "", // domain + false, // secure (true in production) + true, // httpOnly + ) +} + +func (h *Handler) Login(c *gin.Context) { + // var req users.LoginReq + // if err := c.ShouldBindJSON(&req); err != nil { + // c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + // return + // } + // + // res := h.service.Login(req) + // setRefreshTokenCookie(c, res.RefreshToken) + c.JSON(http.StatusOK, gin.H{"msg": "ok"}) +} diff --git a/internal/http/router.go b/internal/http/router.go index a9042ec..abe8963 100644 --- a/internal/http/router.go +++ b/internal/http/router.go @@ -1,14 +1,16 @@ package http import ( + "git.kanopo.dev/rhythm/rhythm-backend/internal/http/api/auth" "git.kanopo.dev/rhythm/rhythm-backend/internal/http/api/health" "github.com/gin-gonic/gin" ) -func GlueRoutes(r *gin.Engine, healthHandler *health.Handler) { +func GlueRoutes(r *gin.Engine, healthHandler *health.Handler, authHandler *auth.Handler) { api := r.Group("/api") healthHandler.RegisterRoutes(api.Group("/health")) - // v1 := api.Group("/v1") + v1 := api.Group("/v1") + authHandler.RegisterRoutes(v1.Group("/auth")) } diff --git a/internal/service/users/user_service.go b/internal/service/users/user_service.go new file mode 100644 index 0000000..f85920c --- /dev/null +++ b/internal/service/users/user_service.go @@ -0,0 +1,34 @@ +package users + +import ( + usersdb "git.kanopo.dev/rhythm/rhythm-backend/internal/db/users" + "go.uber.org/zap" +) + +type Service struct { + repo usersdb.Querier + log *zap.SugaredLogger +} + +func NewService(repo usersdb.Querier, log *zap.SugaredLogger) *Service { + return &Service{ + repo: repo, + log: log, + } +} + +// type LoginReq struct { +// Email string `json:"email" binding:"required"` +// Password string `json:"password" binding:"required"` +// } +// type AuthRes struct { +// AccessToken string `json:"accessToken"` +// RefreshToken string // not parset to json, set with cookies +// } +// +// func (s *Service) Login(req LoginReq) AuthRes { +// return AuthRes{ +// AccessToken: "ciao", +// RefreshToken: "ciao", +// } +// }