package app import ( "context" "encoding/json" "errors" "fmt" "net/http" "strings" "time" "github.com/alexedwards/scs/boltstore" "github.com/alexedwards/scs/v2" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" session "github.com/spazzymoto/echo-scs-session" "gitrepo.ru/neonxp/track/pkg/config" "gitrepo.ru/neonxp/track/pkg/handler" "gitrepo.ru/neonxp/track/pkg/models" "go.etcd.io/bbolt" bolt "go.etcd.io/bbolt" "golang.org/x/crypto/bcrypt" ) func App(ctx context.Context) error { cfg := config.New() db, err := bolt.Open(cfg.DBPath, 0600, nil) if err != nil { return fmt.Errorf("failed open db: %w", err) } defer db.Close() e := echo.New() sessionManager := scs.New() sessionManager.Store = boltstore.NewWithCleanupInterval(db, 5*time.Minute) sessionManager.Lifetime = 30 * 24 * time.Hour userHandler := handler.NewUser(db, sessionManager) locationHandler := handler.NewLocation(db, sessionManager) authFunc := func(s1, s2 string, c echo.Context) (bool, error) { // TODO remove this shit user := new(models.User) s1 = strings.ReplaceAll(s1, "%40", "@") err := db.View(func(tx *bbolt.Tx) error { users := tx.Bucket([]byte("users")) jb := users.Get([]byte(strings.ToLower(s1))) if jb == nil { return errors.New("invalid user or password") } if err := json.Unmarshal(jb, user); err != nil { return err } if err := bcrypt.CompareHashAndPassword(user.Password, []byte(s2)); err != nil { return errors.New("invalid user or password") } return nil }) if err != nil { return false, err } sessionManager.Put(c.Request().Context(), "user", user) return true, nil } func(eg *echo.Group) { eg.POST("/user/register", userHandler.Register) eg.POST("/user/login", userHandler.Login) eg.GET("/user", userHandler.User) eg.GET("/point", locationHandler.AddPoint, middleware.BasicAuth(authFunc)) eg.GET("/points", locationHandler.GetPoints) eg.GET("/points/last", locationHandler.GetLast) }(e.Group("/api")) e.Static("/", "./web") e.Use( middleware.Recover(), middleware.Logger(), session.LoadAndSave(sessionManager), ) if err := e.Start(cfg.Listen); err != http.ErrServerClosed { return err } return nil }