logging to see what is happening
This commit is contained in:
@@ -1,18 +1,20 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
|
"github.com/go-chi/chi/v5/middleware"
|
||||||
"github.com/go-chi/cors"
|
"github.com/go-chi/cors"
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
|
|
||||||
"rideaware/internal/auth"
|
"rideaware/internal/auth"
|
||||||
"rideaware/internal/config"
|
"rideaware/internal/config"
|
||||||
"rideaware/internal/equipment"
|
"rideaware/internal/equipment"
|
||||||
"rideaware/internal/middleware"
|
"rideaware/internal/middlewares"
|
||||||
"rideaware/internal/user"
|
"rideaware/internal/user"
|
||||||
"rideaware/pkg/database"
|
"rideaware/pkg/database"
|
||||||
)
|
)
|
||||||
@@ -40,7 +42,13 @@ func main() {
|
|||||||
|
|
||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
|
|
||||||
// Middleware
|
// Logging middleware
|
||||||
|
r.Use(middleware.RequestID)
|
||||||
|
r.Use(middleware.RealIP)
|
||||||
|
r.Use(loggingMiddleware)
|
||||||
|
r.Use(middleware.Recoverer)
|
||||||
|
|
||||||
|
// CORS middleware
|
||||||
r.Use(cors.Handler(cors.Options{
|
r.Use(cors.Handler(cors.Options{
|
||||||
AllowedOrigins: []string{"*"},
|
AllowedOrigins: []string{"*"},
|
||||||
AllowedMethods: []string{
|
AllowedMethods: []string{
|
||||||
@@ -61,24 +69,39 @@ func main() {
|
|||||||
port = "5000"
|
port = "5000"
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Server running on port %s", port)
|
log.Printf("🚀 Server running on port %s", port)
|
||||||
log.Fatal(http.ListenAndServe(":"+port, r))
|
log.Fatal(http.ListenAndServe(":"+port, r))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Logging middleware
|
||||||
|
func loggingMiddleware(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Printf(
|
||||||
|
"[%s] %s %s %s",
|
||||||
|
r.Method,
|
||||||
|
r.RequestURI,
|
||||||
|
r.RemoteAddr,
|
||||||
|
r.Header.Get("User-Agent"),
|
||||||
|
)
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func setupRoutes(r *chi.Mux) {
|
func setupRoutes(r *chi.Mux) {
|
||||||
// Public routes
|
// Public routes
|
||||||
r.Get("/health", healthCheck)
|
r.Get("/health", healthCheck)
|
||||||
|
|
||||||
// Auth routes - REMOVED /api/ prefix
|
// Auth routes
|
||||||
authHandler := auth.NewHandler()
|
authHandler := auth.NewHandler()
|
||||||
r.Post("/signup", authHandler.Signup)
|
r.Post("/signup", authHandler.Signup)
|
||||||
r.Post("/login", authHandler.Login)
|
r.Post("/login", authHandler.Login)
|
||||||
r.Post("/logout", authHandler.Logout)
|
r.Post("/logout", authHandler.Logout)
|
||||||
r.Post("/password-reset/request", authHandler.RequestPasswordReset)
|
r.Post("/password-reset/request", authHandler.RequestPasswordReset)
|
||||||
r.Post("/password-reset/confirm", authHandler.ConfirmPasswordReset)
|
r.Post("/password-reset/confirm", authHandler.ConfirmPasswordReset)
|
||||||
|
r.Post("/refresh-token", authHandler.RefreshToken)
|
||||||
|
|
||||||
// Protected routes - REMOVED /api/ prefix
|
// Protected routes
|
||||||
authMiddleware := middleware.NewAuthMiddleware()
|
authMiddleware := middlewares.NewAuthMiddleware()
|
||||||
r.Route("/protected", func(r chi.Router) {
|
r.Route("/protected", func(r chi.Router) {
|
||||||
r.Use(authMiddleware.ProtectedRoute)
|
r.Use(authMiddleware.ProtectedRoute)
|
||||||
|
|
||||||
@@ -97,9 +120,12 @@ func setupRoutes(r *chi.Mux) {
|
|||||||
// Training zones
|
// Training zones
|
||||||
r.Get("/zones", equipmentHandler.GetTrainingZones)
|
r.Get("/zones", equipmentHandler.GetTrainingZones)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
log.Println("✅ Routes registered successfully")
|
||||||
}
|
}
|
||||||
|
|
||||||
func healthCheck(w http.ResponseWriter, r *http.Request) {
|
func healthCheck(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Println("📊 Health check called")
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
w.Write([]byte("OK"))
|
w.Write([]byte("OK"))
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ package auth
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"rideaware/internal/config"
|
"rideaware/internal/config"
|
||||||
@@ -41,22 +42,30 @@ type TokenResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) Signup(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) Signup(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Println("📝 Signup request received")
|
||||||
|
|
||||||
var req SignupRequest
|
var req SignupRequest
|
||||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||||
|
log.Printf("❌ Signup decode error: %v", err)
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
json.NewEncoder(w).Encode(map[string]string{"error": "invalid request"})
|
json.NewEncoder(w).Encode(map[string]string{"error": "invalid request"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("📝 Signup attempt for user: %s (email: %s)", req.Username, req.Email)
|
||||||
|
|
||||||
newUser, err := h.userService.CreateUser(req.Username, req.Password, req.Email, req.FirstName, req.LastName)
|
newUser, err := h.userService.CreateUser(req.Username, req.Password, req.Email, req.FirstName, req.LastName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Printf("❌ Signup error: %v", err)
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
json.NewEncoder(w).Encode(map[string]string{"error": err.Error()})
|
json.NewEncoder(w).Encode(map[string]string{"error": err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("✅ User created: %s (ID: %d)", newUser.Username, newUser.ID)
|
||||||
|
|
||||||
accessToken, _ := config.GenerateAccessToken(newUser.ID, newUser.Email, newUser.Username)
|
accessToken, _ := config.GenerateAccessToken(newUser.ID, newUser.Email, newUser.Username)
|
||||||
refreshToken, _ := config.GenerateRefreshToken(newUser.ID, newUser.Email, newUser.Username)
|
refreshToken, _ := config.GenerateRefreshToken(newUser.ID, newUser.Email, newUser.Username)
|
||||||
|
|
||||||
@@ -73,22 +82,30 @@ func (h *Handler) Signup(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) Login(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) Login(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Println("🔐 Login request received")
|
||||||
|
|
||||||
var req LoginRequest
|
var req LoginRequest
|
||||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||||
|
log.Printf("❌ Login decode error: %v", err)
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
json.NewEncoder(w).Encode(map[string]string{"error": "invalid request"})
|
json.NewEncoder(w).Encode(map[string]string{"error": "invalid request"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("🔐 Login attempt for user: %s", req.Username)
|
||||||
|
|
||||||
user, err := h.userService.VerifyUser(req.Username, req.Password)
|
user, err := h.userService.VerifyUser(req.Username, req.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Printf("❌ Login error: %v", err)
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
json.NewEncoder(w).Encode(map[string]string{"error": err.Error()})
|
json.NewEncoder(w).Encode(map[string]string{"error": err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("✅ Login successful for user: %s (ID: %d)", user.Username, user.ID)
|
||||||
|
|
||||||
accessToken, _ := config.GenerateAccessToken(user.ID, user.Email, user.Username)
|
accessToken, _ := config.GenerateAccessToken(user.ID, user.Email, user.Username)
|
||||||
refreshToken, _ := config.GenerateRefreshToken(user.ID, user.Email, user.Username)
|
refreshToken, _ := config.GenerateRefreshToken(user.ID, user.Email, user.Username)
|
||||||
|
|
||||||
@@ -104,25 +121,33 @@ func (h *Handler) Login(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) RefreshToken(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) RefreshToken(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Println("🔄 Refresh token request received")
|
||||||
|
|
||||||
var req struct {
|
var req struct {
|
||||||
RefreshToken string `json:"refresh_token"`
|
RefreshToken string `json:"refresh_token"`
|
||||||
}
|
}
|
||||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||||
|
log.Printf("❌ Refresh token decode error: %v", err)
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
json.NewEncoder(w).Encode(map[string]string{"error": "invalid request"})
|
json.NewEncoder(w).Encode(map[string]string{"error": "invalid request"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Println("🔄 Verifying refresh token...")
|
||||||
|
|
||||||
// Verify refresh token and get user
|
// Verify refresh token and get user
|
||||||
claims, err := config.VerifyRefreshToken(req.RefreshToken)
|
claims, err := config.VerifyRefreshToken(req.RefreshToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Printf("❌ Refresh token verify error: %v", err)
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
json.NewEncoder(w).Encode(map[string]string{"error": "invalid refresh token"})
|
json.NewEncoder(w).Encode(map[string]string{"error": "invalid refresh token"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("✅ Refresh token valid for user ID: %d", claims.UserID)
|
||||||
|
|
||||||
// Generate new access token
|
// Generate new access token
|
||||||
newAccessToken, _ := config.GenerateAccessToken(claims.UserID, claims.Email, claims.Username)
|
newAccessToken, _ := config.GenerateAccessToken(claims.UserID, claims.Email, claims.Username)
|
||||||
|
|
||||||
@@ -134,24 +159,32 @@ func (h *Handler) RefreshToken(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) RequestPasswordReset(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) RequestPasswordReset(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Println("🔑 Password reset request received")
|
||||||
|
|
||||||
var req struct {
|
var req struct {
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
}
|
}
|
||||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||||
|
log.Printf("❌ Password reset decode error: %v", err)
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
json.NewEncoder(w).Encode(map[string]string{"error": "invalid request"})
|
json.NewEncoder(w).Encode(map[string]string{"error": "invalid request"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("🔑 Password reset requested for email: %s", req.Email)
|
||||||
|
|
||||||
err := h.userService.RequestPasswordReset(req.Email)
|
err := h.userService.RequestPasswordReset(req.Email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Printf("❌ Password reset error: %v", err)
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
json.NewEncoder(w).Encode(map[string]string{"error": err.Error()})
|
json.NewEncoder(w).Encode(map[string]string{"error": err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("✅ Password reset email sent to: %s", req.Email)
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
json.NewEncoder(w).Encode(map[string]string{
|
json.NewEncoder(w).Encode(map[string]string{
|
||||||
"message": "If email exists, reset link has been sent",
|
"message": "If email exists, reset link has been sent",
|
||||||
@@ -159,24 +192,32 @@ func (h *Handler) RequestPasswordReset(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) ConfirmPasswordReset(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) ConfirmPasswordReset(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Println("🔑 Password reset confirm request received")
|
||||||
|
|
||||||
var req struct {
|
var req struct {
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
NewPassword string `json:"new_password"`
|
NewPassword string `json:"new_password"`
|
||||||
}
|
}
|
||||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||||
|
log.Printf("❌ Password reset confirm decode error: %v", err)
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
json.NewEncoder(w).Encode(map[string]string{"error": "invalid request"})
|
json.NewEncoder(w).Encode(map[string]string{"error": "invalid request"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Println("🔑 Confirming password reset...")
|
||||||
|
|
||||||
if err := h.userService.ResetPassword(req.Token, req.NewPassword); err != nil {
|
if err := h.userService.ResetPassword(req.Token, req.NewPassword); err != nil {
|
||||||
|
log.Printf("❌ Password reset confirm error: %v", err)
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
json.NewEncoder(w).Encode(map[string]string{"error": err.Error()})
|
json.NewEncoder(w).Encode(map[string]string{"error": err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Println("✅ Password reset successful")
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
json.NewEncoder(w).Encode(map[string]string{
|
json.NewEncoder(w).Encode(map[string]string{
|
||||||
"message": "Password reset successful",
|
"message": "Password reset successful",
|
||||||
@@ -184,6 +225,7 @@ func (h *Handler) ConfirmPasswordReset(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) Logout(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) Logout(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Println("👋 Logout request received")
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
json.NewEncoder(w).Encode(map[string]string{"message": "Logout successful"})
|
json.NewEncoder(w).Encode(map[string]string{"message": "Logout successful"})
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user