package lib import ( "database/sql" "errors" "net/http" "github.com/labstack/echo/v4" "golang.org/x/crypto/bcrypt" ) type User struct { ID string Name string Email string Password string } // HashPassword hashes the given password using bcrypt. func HashPassword(password string) (string, error) { bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) return string(bytes), err } // CheckPasswordHash checks if the given password matches the hashed password. func CheckPasswordHash(password, hash string) bool { err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) return err == nil } // GetUserByEmail fetches a user by email from the database. func GetUserByEmail(db *sql.DB, email string) (*User, error) { if db == nil { return nil, errors.New("database client is not initialized") } var user User row := db.QueryRow( "SELECT id, name, email, password FROM users WHERE email = ?", email) err := row.Scan(&user.ID, &user.Name, &user.Email, &user.Password) if err != nil { return nil, err } return &user, nil } // GetUserByID fetches a user by ID from the database. func GetUserByID(db *sql.DB, id string) (*User, error) { if db == nil { return nil, errors.New("database client is not initialized") } var user User row := db.QueryRow( "SELECT id, name, email, password FROM users WHERE id = ?", id) err := row.Scan(&user.ID, &user.Name, &user.Email, &user.Password) if err != nil { return nil, err } return &user, nil } // SaveUser saves a new user to the database. func SaveUser(db *sql.DB, user *User) error { if db == nil { return errors.New("database client is not initialized") } result, err := db.Exec( "INSERT INTO users (id, name, email, password) VALUES (?, ?, ?, ?)", GenerateNewID("user"), user.Name, user.Email, user.Password) if err != nil { return err } rowsAffected, _ := result.RowsAffected() if rowsAffected != 1 { return errors.New("expected one row to be affected") } return nil } func AuthenticatedPageMiddleware(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { isSignedIn := IsSignedIn(c) // Check if user is authenticated if !isSignedIn { // Redirect to signin page if not authenticated return c.Redirect(http.StatusFound, "/signin") } // Proceed with the request if authenticated return next(c) } } func AuthFlowPageMiddleware(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { isSignedIn := IsSignedIn(c) if isSignedIn { return c.Redirect(http.StatusFound, "/dashboard") } return next(c) } } func AuthenticatedEndpointMiddleware(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { isSignedIn := IsSignedIn(c) // Check if user is authenticated if !isSignedIn { // Return 401 if not authenticated return c.String(http.StatusUnauthorized, "Unauthorized") } // Proceed with the request if authenticated return next(c) } }