From 235ca025ca5c40cde03d91e9942bf591172cd67e Mon Sep 17 00:00:00 2001 From: vovanbravin Date: Sun, 24 May 2026 22:47:37 +0300 Subject: [PATCH 1/2] feat/add_firstname_and_lastname --- cmd/api-gateway/main.go | 20 +++++++++----- go.mod | 1 + go.sum | 2 ++ internal/auth/handler/http.go | 34 +++++++++++++++--------- internal/auth/model/model.go | 2 ++ internal/auth/service/auth.go | 22 ++++++++------- internal/auth/storage/user_repository.go | 6 +++-- migrations/1_create_tables.up.sql | 2 ++ pkg/dto/dto.go | 6 +++-- web/index.html | 7 ----- 10 files changed, 62 insertions(+), 40 deletions(-) delete mode 100644 web/index.html diff --git a/cmd/api-gateway/main.go b/cmd/api-gateway/main.go index fedee1f..2140662 100644 --- a/cmd/api-gateway/main.go +++ b/cmd/api-gateway/main.go @@ -1,6 +1,7 @@ package main import ( + "github.com/rs/cors" "log" "net/http" "net/http/httputil" @@ -15,19 +16,26 @@ func main() { Host: "auth-service:8081"}), } - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + fs := http.FileServer(http.Dir("./web")) + + mainHandler := func(w http.ResponseWriter, r *http.Request) { for prefix, proxy := range proxies { if strings.HasPrefix(r.URL.Path, prefix) { - log.Printf("Proxy %s\n", r.URL.Path) + log.Printf("Proxy %s %s", r.Method, r.URL.Path) proxy.ServeHTTP(w, r) return } } - log.Printf("No found url: %s\n", r.URL.Path) - http.NotFound(w, r) - }) + fs.ServeHTTP(w, r) + } + + mux := http.NewServeMux() + + mux.HandleFunc("/", mainHandler) + + handler := cors.Default().Handler(mux) - if err := http.ListenAndServe(":8080", nil); err != nil { + if err := http.ListenAndServe(":8080", handler); err != nil { log.Fatal(err.Error()) } diff --git a/go.mod b/go.mod index 1438701..f657dae 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect + github.com/rs/cors v1.11.1 // indirect golang.org/x/sync v0.20.0 // indirect golang.org/x/text v0.36.0 // indirect ) diff --git a/go.sum b/go.sum index 9901e05..7c80f54 100644 --- a/go.sum +++ b/go.sum @@ -19,6 +19,8 @@ github.com/pelletier/go-toml/v2 v2.3.1 h1:MYEvvGnQjeNkRF1qUuGolNtNExTDwct51yp7ol github.com/pelletier/go-toml/v2 v2.3.1/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= +github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= diff --git a/internal/auth/handler/http.go b/internal/auth/handler/http.go index ff65e64..088f72a 100644 --- a/internal/auth/handler/http.go +++ b/internal/auth/handler/http.go @@ -16,19 +16,26 @@ func NewAuthHandler(authService *service.AuthService) *AuthHandler { return &AuthHandler{authService: authService} } +func SetError(w http.ResponseWriter, message string, statusCode int) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(statusCode) + json.NewEncoder(w).Encode(map[string]string{ + "message": message, + }) +} + func (h *AuthHandler) RegisterHandler(w http.ResponseWriter, r *http.Request) { var req dto.RegisterRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - http.Error(w, "invalid body", http.StatusBadRequest) + SetError(w, "invalid body", http.StatusBadRequest) return } - tokens, err := h.authService.Register(r.Context(), req.Email, req.Password) + tokens, err := h.authService.Register(r.Context(), req) if err != nil { - log.Printf("Registration error: %v", err) - http.Error(w, err.Error(), http.StatusBadRequest) + SetError(w, err.Error(), http.StatusBadRequest) return } @@ -40,9 +47,10 @@ func (h *AuthHandler) RegisterHandler(w http.ResponseWriter, r *http.Request) { "access_token": tokens.AccessToken, "expires_at": tokens.ExpiresAt, }) + if err != nil { - log.Printf("json encode error: %v", err) - http.Error(w, err.Error(), http.StatusBadRequest) + SetError(w, err.Error(), http.StatusBadRequest) + return } } @@ -50,15 +58,15 @@ func (h *AuthHandler) Login(w http.ResponseWriter, r *http.Request) { var req dto.LoginRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - http.Error(w, "invalid body", http.StatusBadRequest) + SetError(w, "invalid body", http.StatusBadRequest) return } - tokens, err := h.authService.Login(r.Context(), req.Email, req.Password) + tokens, err := h.authService.Login(r.Context(), req) if err != nil { log.Printf("Registration error: %v", err) - http.Error(w, err.Error(), http.StatusBadRequest) + SetError(w, err.Error(), http.StatusBadRequest) return } @@ -72,21 +80,21 @@ func (h *AuthHandler) Login(w http.ResponseWriter, r *http.Request) { }) if err != nil { log.Printf("json encode error: %v", err) - http.Error(w, err.Error(), http.StatusBadRequest) + SetError(w, err.Error(), http.StatusBadRequest) } } func (h *AuthHandler) Refresh(w http.ResponseWriter, r *http.Request) { cookie, err := r.Cookie("refresh_token") if err != nil { - http.Error(w, "missing refresh token", http.StatusUnauthorized) + SetError(w, "missing refresh token", http.StatusUnauthorized) return } tokens, err := h.authService.RefreshAccessToken(r.Context(), cookie.Value) if err != nil { - http.Error(w, "invalid refresh token", http.StatusUnauthorized) + SetError(w, "invalid refresh token", http.StatusUnauthorized) log.Fatalf("Error: %v", err.Error()) return } @@ -101,7 +109,7 @@ func (h *AuthHandler) Refresh(w http.ResponseWriter, r *http.Request) { }) if err != nil { log.Printf("json encode error: %v", err) - http.Error(w, err.Error(), http.StatusBadRequest) + SetError(w, err.Error(), http.StatusBadRequest) } } diff --git a/internal/auth/model/model.go b/internal/auth/model/model.go index 65d1835..3e4ae5a 100644 --- a/internal/auth/model/model.go +++ b/internal/auth/model/model.go @@ -18,4 +18,6 @@ type User struct { Email string `db:"email"` PasswordHash string `db:"password_hash"` CreatedAt time.Time `db:"created_at"` + Firstname string `db:"firstname"` + Lastname string `db:"lastname"` } diff --git a/internal/auth/service/auth.go b/internal/auth/service/auth.go index 2477631..f9e1ebe 100644 --- a/internal/auth/service/auth.go +++ b/internal/auth/service/auth.go @@ -32,17 +32,17 @@ func NewAuthService(hasher *infrastructure.BcryptHasher, return &AuthService{hasher: hasher, tokensRepo: tokensRepo, userRepo: userRepo, jwt: jwt} } -func (s *AuthService) Register(ctx context.Context, email, password string) (*dto.TokenResponse, error) { +func (s *AuthService) Register(ctx context.Context, request dto.RegisterRequest) (*dto.TokenResponse, error) { - if email == "" { + if request.Email == "" { return nil, ErrInvalidEmail } - if utf8.RuneCountInString(password) < 6 { + if utf8.RuneCountInString(request.Password) < 6 { return nil, ErrWeakPassword } - exists, err := s.userRepo.Exists(ctx, email) + exists, err := s.userRepo.Exists(ctx, request.Email) if err != nil { return nil, err @@ -51,23 +51,25 @@ func (s *AuthService) Register(ctx context.Context, email, password string) (*dt return nil, ErrUserAlreadyExists } - hash, err := s.hasher.Hash(password) + hash, err := s.hasher.Hash(request.Password) if err != nil { return nil, err } user := &model.User{ ID: uuid.NewString(), - Email: email, + Email: request.Email, PasswordHash: hash, CreatedAt: time.Now().UTC(), + Firstname: request.Firstname, + Lastname: request.Lastname, } if err = s.userRepo.Create(ctx, user); err != nil { return nil, err } - tokens, err := s.jwt.Generate(user.ID, email) + tokens, err := s.jwt.Generate(user.ID, request.Email) if err != nil { return nil, err @@ -93,15 +95,15 @@ func (s *AuthService) Register(ctx context.Context, email, password string) (*dt }, nil } -func (s *AuthService) Login(ctx context.Context, email, password string) (*dto.TokenResponse, error) { +func (s *AuthService) Login(ctx context.Context, request dto.LoginRequest) (*dto.TokenResponse, error) { - user, err := s.userRepo.GetByEmail(ctx, email) + user, err := s.userRepo.GetByEmail(ctx, request.Email) if err != nil { return nil, errors.New("invalid credentials") } - if err = s.hasher.Verify(password, user.PasswordHash); err != nil { + if err = s.hasher.Verify(request.Password, user.PasswordHash); err != nil { return nil, errors.New("invalid credentials") } diff --git a/internal/auth/storage/user_repository.go b/internal/auth/storage/user_repository.go index 7268c73..eeb03a1 100644 --- a/internal/auth/storage/user_repository.go +++ b/internal/auth/storage/user_repository.go @@ -23,8 +23,10 @@ func NewUserRepository(db *pgxpool.Pool) *UserRepository { } func (r *UserRepository) Create(ctx context.Context, user *model.User) error { - _, err := r.db.Exec(ctx, `INSERT INTO users (id, email, password_hash, - created_at) VALUES ($1, $2, $3, $4)`, user.ID, user.Email, user.PasswordHash, user.CreatedAt) + _, err := r.db.Exec(ctx, `INSERT INTO users (id, email, firstname, lastname,password_hash, + created_at) VALUES ($1, $2, $3, $4, $5, $6)`, user.ID, user.Email, + user.Firstname, user.Lastname, user.PasswordHash, + user.CreatedAt) return err } diff --git a/migrations/1_create_tables.up.sql b/migrations/1_create_tables.up.sql index edb4f7a..7b53a4b 100644 --- a/migrations/1_create_tables.up.sql +++ b/migrations/1_create_tables.up.sql @@ -1,6 +1,8 @@ CREATE TABLE users ( id text primary key, email text not null unique, + firstname text not null, + lastname text not null, password_hash text not null, created_at timestamptz not null ); diff --git a/pkg/dto/dto.go b/pkg/dto/dto.go index e5ec130..7d5e5c4 100644 --- a/pkg/dto/dto.go +++ b/pkg/dto/dto.go @@ -15,8 +15,10 @@ type TokenResponse struct { } type RegisterRequest struct { - Email string `json:"email"` - Password string `json:"password"` + Firstname string `json:"firstname"` + Lastname string `json:"lastname"` + Email string `json:"email"` + Password string `json:"password"` } type LoginRequest struct { diff --git a/web/index.html b/web/index.html deleted file mode 100644 index 78866cc..0000000 --- a/web/index.html +++ /dev/null @@ -1,7 +0,0 @@ - - -EventFlow - - - - \ No newline at end of file From a9433ad69f15bbc1a1461351ac7264e0ac560565 Mon Sep 17 00:00:00 2001 From: vovanbravin Date: Sun, 24 May 2026 23:47:06 +0300 Subject: [PATCH 2/2] fix golang-lint --- internal/auth/handler/http.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/auth/handler/http.go b/internal/auth/handler/http.go index 088f72a..f74a954 100644 --- a/internal/auth/handler/http.go +++ b/internal/auth/handler/http.go @@ -19,7 +19,7 @@ func NewAuthHandler(authService *service.AuthService) *AuthHandler { func SetError(w http.ResponseWriter, message string, statusCode int) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(statusCode) - json.NewEncoder(w).Encode(map[string]string{ + _ = json.NewEncoder(w).Encode(map[string]string{ "message": message, }) }