Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions cmd/api-gateway/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"github.com/rs/cors"
"log"
"net/http"
"net/http/httputil"
Expand All @@ -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())
}

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
34 changes: 21 additions & 13 deletions internal/auth/handler/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand All @@ -40,25 +47,26 @@ 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
}
}

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
}

Expand All @@ -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
}
Expand All @@ -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)
}

}
Expand Down
2 changes: 2 additions & 0 deletions internal/auth/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
}
22 changes: 12 additions & 10 deletions internal/auth/service/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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")
}

Expand Down
6 changes: 4 additions & 2 deletions internal/auth/storage/user_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
2 changes: 2 additions & 0 deletions migrations/1_create_tables.up.sql
Original file line number Diff line number Diff line change
@@ -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
);
Expand Down
6 changes: 4 additions & 2 deletions pkg/dto/dto.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
7 changes: 0 additions & 7 deletions web/index.html

This file was deleted.

Loading