reset user password
This commit is contained in:
@@ -9,6 +9,7 @@ require (
|
||||
github.com/labstack/echo/v4 v4.13.4
|
||||
github.com/strukturag/libheif-go v0.0.0-20250130134905-55b3482bea15
|
||||
golang.org/x/crypto v0.44.0
|
||||
golang.org/x/term v0.39.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -18,7 +19,7 @@ require (
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
golang.org/x/net v0.47.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
golang.org/x/sys v0.40.0 // indirect
|
||||
golang.org/x/text v0.31.0 // indirect
|
||||
golang.org/x/time v0.14.0 // indirect
|
||||
)
|
||||
|
||||
@@ -27,8 +27,10 @@ golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvm
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
||||
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
|
||||
golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
||||
|
||||
@@ -112,6 +112,19 @@ func VerifyPassword(user *User, password string) bool {
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// GetUsernameByID retrieves username by user ID
|
||||
func GetUsernameByID(userID string) (string, error) {
|
||||
var username string
|
||||
err := authDB.QueryRow("SELECT username FROM users WHERE id = ?", userID).Scan(&username)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return "", fmt.Errorf("user not found")
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
return username, nil
|
||||
}
|
||||
|
||||
// GenerateSessionID generates a random session ID
|
||||
func GenerateSessionID() (string, error) {
|
||||
bytes := make([]byte, 32)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
@@ -10,11 +12,16 @@ import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
"github.com/lowcarbdev/sbv/internal"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
var logger *slog.Logger
|
||||
|
||||
func main() {
|
||||
// Parse CLI flags
|
||||
resetPassword := flag.String("reset-password", "", "Reset password for the specified username")
|
||||
flag.Parse()
|
||||
|
||||
// Initialize slog logger
|
||||
logger = slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
|
||||
Level: slog.LevelInfo,
|
||||
@@ -35,6 +42,15 @@ func main() {
|
||||
}
|
||||
logger.Info("Authentication database initialized", "path", authDBPath)
|
||||
|
||||
// Handle password reset if requested
|
||||
if *resetPassword != "" {
|
||||
if err := handleResetPassword(*resetPassword); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// Create Echo instance
|
||||
e := echo.New()
|
||||
|
||||
@@ -145,3 +161,45 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// handleResetPassword prompts for a new password and resets it for the given username
|
||||
func handleResetPassword(username string) error {
|
||||
// Look up the user
|
||||
user, err := internal.GetUserByUsername(username)
|
||||
if err != nil {
|
||||
return fmt.Errorf("user '%s' not found", username)
|
||||
}
|
||||
|
||||
// Prompt for new password
|
||||
fmt.Print("Enter new password: ")
|
||||
passwordBytes, err := term.ReadPassword(int(os.Stdin.Fd()))
|
||||
fmt.Println()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read password: %w", err)
|
||||
}
|
||||
|
||||
// Prompt for password confirmation
|
||||
fmt.Print("Confirm new password: ")
|
||||
confirmBytes, err := term.ReadPassword(int(os.Stdin.Fd()))
|
||||
fmt.Println()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read password confirmation: %w", err)
|
||||
}
|
||||
|
||||
password := string(passwordBytes)
|
||||
if password != string(confirmBytes) {
|
||||
return fmt.Errorf("passwords do not match")
|
||||
}
|
||||
|
||||
if len(password) < 6 {
|
||||
return fmt.Errorf("password must be at least 6 characters")
|
||||
}
|
||||
|
||||
// Update the password
|
||||
if err := internal.UpdatePassword(user.ID, password); err != nil {
|
||||
return fmt.Errorf("failed to update password: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Password reset successfully for user '%s'\n", username)
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user