package handlers import ( "log" "net/http" "threadr/models" "github.com/gorilla/sessions" ) func PasswordHandler(app *App) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { session := r.Context().Value("session").(*sessions.Session) userID, ok := session.Values["user_id"].(int) if !ok { http.Redirect(w, r, app.Config.ThreadrDir+"/login/", http.StatusFound) return } user, err := models.GetUserByID(app.DB, userID) if err != nil { log.Printf("Error fetching user in PasswordHandler: %v", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } if user == nil { http.Error(w, "User not found", http.StatusNotFound) return } cookie, _ := r.Cookie("threadr_cookie_banner") if r.Method == http.MethodPost { currentPassword := r.FormValue("current_password") newPassword := r.FormValue("new_password") confirmPassword := r.FormValue("confirm_password") if currentPassword == "" || newPassword == "" || confirmPassword == "" { renderPasswordPage(app, w, r, session, cookie, "All fields are required.", false) return } if !models.CheckPassword(currentPassword, user.AuthenticationSalt, user.AuthenticationAlgorithm, user.AuthenticationString) { renderPasswordPage(app, w, r, session, cookie, "Current password is incorrect.", false) return } if newPassword != confirmPassword { renderPasswordPage(app, w, r, session, cookie, "New passwords do not match.", false) return } if len(newPassword) < 8 { renderPasswordPage(app, w, r, session, cookie, "New password must be at least 8 characters.", false) return } if err := models.UpdateUserPassword(app.DB, userID, newPassword); err != nil { log.Printf("Error updating password: %v", err) renderPasswordPage(app, w, r, session, cookie, "Failed to update password. Please try again.", false) return } http.Redirect(w, r, app.Config.ThreadrDir+"/password/?saved=true", http.StatusFound) return } showSuccess := r.URL.Query().Get("saved") == "true" renderPasswordPage(app, w, r, session, cookie, "", showSuccess) } } func renderPasswordPage(app *App, w http.ResponseWriter, r *http.Request, session *sessions.Session, cookie *http.Cookie, errMsg string, showSuccess bool) { data := struct { PageData Error string ShowSuccess bool }{ PageData: PageData{ Title: "ThreadR - Change Password", Navbar: "password", LoggedIn: true, AllowSignup: app.allowSignup(), ShowCookieBanner: cookie == nil || cookie.Value != "accepted", BasePath: app.Config.ThreadrDir, StaticPath: app.Config.ThreadrDir + "/static", CurrentURL: r.URL.RequestURI(), }, Error: errMsg, ShowSuccess: showSuccess, } if err := app.Tmpl.ExecuteTemplate(w, "password", data); err != nil { log.Printf("Error executing template in PasswordHandler: %v", err) } }