fix: auth flow fixed, add getOrCreate method for user
This commit is contained in:
parent
406b181576
commit
7d7f54261b
@ -73,7 +73,7 @@ func (h *AuthHandler) Authenticate(c *fiber.Ctx) error {
|
|||||||
c.Context(),
|
c.Context(),
|
||||||
req.PubKey,
|
req.PubKey,
|
||||||
req.Signature,
|
req.Signature,
|
||||||
// add chainID to cfg
|
//TODO: add chainID to cfg
|
||||||
1,
|
1,
|
||||||
c.IP(),
|
c.IP(),
|
||||||
c.Get("User-Agent"),
|
c.Get("User-Agent"),
|
||||||
@ -90,3 +90,9 @@ func (h *AuthHandler) Authenticate(c *fiber.Ctx) error {
|
|||||||
ExpiresAt: userToken.ExpiresAt,
|
ExpiresAt: userToken.ExpiresAt,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *AuthHandler) HelloWorld(c *fiber.Ctx) error {
|
||||||
|
return c.Status(fiber.StatusOK).JSON(fiber.Map{
|
||||||
|
"message": "Hello, World!",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import (
|
|||||||
"backend/config"
|
"backend/config"
|
||||||
"backend/docs"
|
"backend/docs"
|
||||||
httpHandlers "backend/internal/api/http/handlers"
|
httpHandlers "backend/internal/api/http/handlers"
|
||||||
|
"backend/internal/api/http/middlewares"
|
||||||
"backend/internal/app"
|
"backend/internal/app"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
@ -14,19 +15,27 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func Run(cfg config.Server, app *app.AppContainer) {
|
func Run(cfg config.Server, app *app.AppContainer) {
|
||||||
router := fiber.New()
|
fiberApp := fiber.New()
|
||||||
|
|
||||||
api := router.Group("/api")
|
// Serve static files (HTML, CSS, JS)
|
||||||
|
fiberApp.Static("/", "./")
|
||||||
|
|
||||||
|
api := fiberApp.Group("/api")
|
||||||
|
// register routes here
|
||||||
registerPublicRoutes(api, app)
|
registerPublicRoutes(api, app)
|
||||||
|
|
||||||
docs.SwaggerInfo.Host = ""
|
docs.SwaggerInfo.Host = fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)
|
||||||
docs.SwaggerInfo.Schemes = []string{}
|
|
||||||
docs.SwaggerInfo.BasePath = "/api"
|
docs.SwaggerInfo.BasePath = "/api"
|
||||||
|
docs.SwaggerInfo.Schemes = []string{"http", "https"}
|
||||||
|
|
||||||
router.Get("/swagger/*", adaptor.HTTPHandler(httpSwagger.Handler()))
|
api.Get("/swagger/*", adaptor.HTTPHandler(httpSwagger.Handler()))
|
||||||
|
|
||||||
log.Fatal(router.Listen(fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)))
|
api.Get("/hello", middlewares.JWTAuthMiddleware([]byte("Secret")), func(c *fiber.Ctx) error {
|
||||||
|
return c.SendString("Hello, World!")
|
||||||
|
})
|
||||||
|
|
||||||
|
log.Printf("Server starting on %s:%d", cfg.Host, cfg.Port)
|
||||||
|
log.Fatal(fiberApp.Listen(fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerPublicRoutes(router fiber.Router, app *app.AppContainer) {
|
func registerPublicRoutes(router fiber.Router, app *app.AppContainer) {
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import (
|
|||||||
"backend/config"
|
"backend/config"
|
||||||
"backend/internal/repository/cache"
|
"backend/internal/repository/cache"
|
||||||
"backend/internal/repository/storage"
|
"backend/internal/repository/storage"
|
||||||
|
"backend/internal/repository/storage/types"
|
||||||
"backend/internal/usecase"
|
"backend/internal/usecase"
|
||||||
cachePackage "backend/pkg/cache"
|
cachePackage "backend/pkg/cache"
|
||||||
"backend/pkg/postgres"
|
"backend/pkg/postgres"
|
||||||
@ -32,6 +33,7 @@ func NewAppContainer(cfg config.Config) (*AppContainer, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to connect to database: %w", err)
|
return nil, fmt.Errorf("failed to connect to database: %w", err)
|
||||||
}
|
}
|
||||||
|
dbConn.AutoMigrate(&types.User{})
|
||||||
|
|
||||||
redis, err := cachePackage.NewRedis(cfg.Redis)
|
redis, err := cachePackage.NewRedis(cfg.Redis)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -28,6 +28,7 @@ type UserRepo interface {
|
|||||||
GetByID(ctx context.Context, id uuid.UUID) (*User, error)
|
GetByID(ctx context.Context, id uuid.UUID) (*User, error)
|
||||||
GetByPhone(ctx context.Context, phone string) (*User, error)
|
GetByPhone(ctx context.Context, phone string) (*User, error)
|
||||||
GetByPubKey(ctx context.Context, pubKey string) (*User, error)
|
GetByPubKey(ctx context.Context, pubKey string) (*User, error)
|
||||||
|
GetOrCreateUserByPubKey(ctx context.Context, pubKey string) (*User, error)
|
||||||
Update(ctx context.Context, user *User) error
|
Update(ctx context.Context, user *User) error
|
||||||
Delete(ctx context.Context, id uuid.UUID) error
|
Delete(ctx context.Context, id uuid.UUID) error
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,11 +4,19 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Base struct {
|
type Base struct {
|
||||||
ID uuid.UUID
|
ID uuid.UUID `gorm:"type:uuid;default:uuid_generate_v4();primaryKey"`
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
DeletedAt *time.Time
|
DeletedAt *time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *Base) BeforeCreate(tx *gorm.DB) (err error) {
|
||||||
|
if b.ID == uuid.Nil {
|
||||||
|
b.ID = uuid.New()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
@ -27,6 +27,7 @@ func CastUserToStorage(u domain.User) *User {
|
|||||||
UpdatedAt: u.UpdatedAt,
|
UpdatedAt: u.UpdatedAt,
|
||||||
DeletedAt: u.DeletedAt,
|
DeletedAt: u.DeletedAt,
|
||||||
},
|
},
|
||||||
|
PubKey: u.PubKey,
|
||||||
Name: u.Name,
|
Name: u.Name,
|
||||||
LastName: u.LastName,
|
LastName: u.LastName,
|
||||||
Phone: u.PhoneNumber,
|
Phone: u.PhoneNumber,
|
||||||
@ -40,6 +41,7 @@ func CastUserToStorage(u domain.User) *User {
|
|||||||
func CastUserToDomain(u User) *domain.User {
|
func CastUserToDomain(u User) *domain.User {
|
||||||
return &domain.User{
|
return &domain.User{
|
||||||
ID: u.ID,
|
ID: u.ID,
|
||||||
|
PubKey: u.PubKey,
|
||||||
Name: u.Name,
|
Name: u.Name,
|
||||||
LastName: u.LastName,
|
LastName: u.LastName,
|
||||||
PhoneNumber: u.Phone,
|
PhoneNumber: u.Phone,
|
||||||
|
|||||||
@ -20,8 +20,12 @@ func NewUserRepository(db *gorm.DB) domain.UserRepo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *UserRepository) Create(ctx context.Context, user *domain.User) error {
|
func (r *UserRepository) Create(ctx context.Context, user *domain.User) error {
|
||||||
var model types.User
|
model := types.CastUserToStorage(*user)
|
||||||
return r.db.WithContext(ctx).Create(&model).Error
|
if err := r.db.WithContext(ctx).Create(model).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*user = *types.CastUserToDomain(*model)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *UserRepository) GetByID(ctx context.Context, id uuid.UUID) (*domain.User, error) {
|
func (r *UserRepository) GetByID(ctx context.Context, id uuid.UUID) (*domain.User, error) {
|
||||||
@ -56,3 +60,22 @@ func (r *UserRepository) GetByPubKey(ctx context.Context, pubKey string) (*domai
|
|||||||
}
|
}
|
||||||
return types.CastUserToDomain(user), nil
|
return types.CastUserToDomain(user), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *UserRepository) GetOrCreateUserByPubKey(ctx context.Context, pubKey string) (*domain.User, error) {
|
||||||
|
var user types.User
|
||||||
|
err := r.db.WithContext(ctx).First(&user, "pub_key = ?", pubKey).Error
|
||||||
|
if err == nil {
|
||||||
|
return types.CastUserToDomain(user), nil
|
||||||
|
}
|
||||||
|
if err != gorm.ErrRecordNotFound {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
user = types.User{
|
||||||
|
PubKey: pubKey,
|
||||||
|
}
|
||||||
|
if err := r.db.WithContext(ctx).Create(&user).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return types.CastUserToDomain(user), nil
|
||||||
|
}
|
||||||
|
|||||||
@ -98,16 +98,14 @@ func (s *authService) Authenticate(ctx context.Context, pubKey string, signature
|
|||||||
return nil, fmt.Errorf("failed to delete challenge: %w", err)
|
return nil, fmt.Errorf("failed to delete challenge: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := s.userRepo.GetByPubKey(ctx, pubKey)
|
user, err := s.userRepo.GetOrCreateUserByPubKey(ctx, pubKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("failed to get or create user: %w", err)
|
||||||
}
|
|
||||||
if user == nil {
|
|
||||||
return nil, domain.ErrUserNotFound
|
|
||||||
}
|
}
|
||||||
|
|
||||||
user.UpdateLastLogin()
|
user.UpdateLastLogin()
|
||||||
if err := s.userRepo.Update(ctx, user); err != nil {
|
if err := s.userRepo.Update(ctx, user); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("failed to update user: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
expiresAt := time.Now().Add(time.Duration(s.cfg.TokenExpMinutes) * time.Minute)
|
expiresAt := time.Now().Add(time.Duration(s.cfg.TokenExpMinutes) * time.Minute)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user