package pages import ( "context" "fmt" "gosten/csrf" "gosten/form" "gosten/model" "net/http" "github.com/go-chi/chi/v5" "golang.org/x/crypto/bcrypt" ) type chpw struct { Password string `form:"type=password;options=required"` NewPw1 string `form:"label=Neues Password;type=password;options=required"` NewPw2 string `form:"label=Wiederholung;type=password;options=required"` Success bool `form:"-"` form.FormErrors csrf.CsrfField } func ChangePassword() Page { r := chi.NewRouter() r.Get("/", func(w http.ResponseWriter, r *http.Request) { c := chpw{} c.SetCsrfField(r) render(changePassword(c))(w, r) }) r.Post("/", handleChPw) return r } func handleChPw(w http.ResponseWriter, r *http.Request) { c := chpw{} form.Parse(r, &c) ctx := r.Context() userId := getUser(ctx).ID dbPwd, err := Q.GetPwdById(ctx, userId) if err != nil { panic(fmt.Sprintf("Q.GetPwdById: %v", err)) } if c.NewPw1 != c.NewPw2 { c.AddError("NewPw2", "Neues Passwort stimmt nicht überein!") } if !validatePwd(dbPwd, c.Password) { c.AddError("Password", "Passwort falsch!") } if !c.HasError() { updatePwd(ctx, userId, c.NewPw1) // update context ctx, _ = setUserInContext(ctx, userId) r = r.WithContext(ctx) // reset form c = chpw{Success: true} } c.SetCsrfField(r) render(changePassword(c))(w, r) } func updatePwd(ctx context.Context, userId int32, pwd string) { hash, err := bcrypt.GenerateFromPassword([]byte(pwd), -1) if err != nil { panic(fmt.Sprintf("Generating password hash: %v", err)) } err = Q.UpdatePwd(ctx, model.UpdatePwdParams{ Pwd: string(hash), ID: userId}) if err != nil { panic(fmt.Sprintf("Updating password: %v", err)) } }