Files
addrss.io/pkg/auth/password.go
2025-09-06 21:35:45 -04:00

75 lines
1.7 KiB
Go

package auth
import (
"addrss/pkg/repo"
"fmt"
"math/rand"
"time"
"golang.org/x/crypto/bcrypt"
)
type NewPassword struct {
Password string `json:"-"`
Hash string `json:"-"`
}
type PasswordChange struct {
UserId int64 `json:"userId"`
OldPassword string `json:"oldPassword"`
NewPassword string `json:"newPassword"`
ConfirmPassword string `json:"confirmPassword"`
}
func ChangePassword(pc PasswordChange) error {
u, err := repo.GetUserById(pc.UserId)
if err != nil {
return fmt.Errorf("could not get user for user id %d: %v", pc.UserId, err)
}
if err = bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(pc.OldPassword)); err != nil {
return fmt.Errorf("incorrect password for user id %d", pc.UserId)
}
h, err := bcrypt.GenerateFromPassword([]byte(pc.NewPassword), bcrypt.DefaultCost)
if err != nil {
return fmt.Errorf("bcrypt error: %v", err)
}
u.Password = string(h)
if err = repo.UpdateUserPassword(u); err != nil {
return fmt.Errorf("failed to update password for user id %d: %v", u.Id, err)
}
return nil
}
func GetRandomPassword(length int) (NewPassword, error) {
p := GetRandomString(length)
h, err := bcrypt.GenerateFromPassword([]byte(p), bcrypt.DefaultCost)
if err != nil {
return NewPassword{}, err
}
np := NewPassword{
Password: p,
Hash: string(h),
}
return np, nil
}
// GetRandomString Keep as a separate function in case this becomes useful for some other purpose
func GetRandomString(length int) string {
const chars = "!@#$%?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
b := make([]byte, length)
for i := range b {
b[i] = chars[rnd.Intn(len(chars))]
}
return string(b)
}