diff options
Diffstat (limited to '')
-rw-r--r-- | pages/chpw.go | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/pages/chpw.go b/pages/chpw.go new file mode 100644 index 0000000..671c180 --- /dev/null +++ b/pages/chpw.go @@ -0,0 +1,84 @@ +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)) + } +} |