package handler import ( "context" "net/http" "time" "projectreshoot/internal/models" "projectreshoot/internal/view/component/form" "git.haelnorr.com/h/golib/hws" "git.haelnorr.com/h/golib/hwsauth" "github.com/pkg/errors" "github.com/uptrace/bun" ) // Validate the provided password func validatePassword( ctx context.Context, auth *hwsauth.Authenticator[*models.UserBun, bun.Tx], tx bun.Tx, r *http.Request, ) error { r.ParseForm() password := r.FormValue("password") user := auth.CurrentModel(r.Context()) err := user.CheckPassword(ctx, tx, password) if err != nil { return errors.Wrap(err, "user.CheckPassword") } return nil } // Handle request to reauthenticate (i.e. make token fresh again) func Reauthenticate( server *hws.Server, auth *hwsauth.Authenticator[*models.UserBun, bun.Tx], db *bun.DB, ) http.Handler { return http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second) defer cancel() // Start the transaction tx, err := db.BeginTx(ctx, nil) if err != nil { err := server.ThrowError(w, r, hws.HWSError{ StatusCode: http.StatusInternalServerError, Message: "Failed to start transcation", Error: err, }) if err != nil { server.ThrowFatal(w, err) } return } defer tx.Rollback() err = validatePassword(ctx, auth, tx, r) if err != nil { w.WriteHeader(445) form.ConfirmPassword("Incorrect password").Render(r.Context(), w) return } err = auth.RefreshAuthTokens(tx, w, r) if err != nil { err := server.ThrowError(w, r, hws.HWSError{ StatusCode: http.StatusInternalServerError, Message: "Failed to refresh user tokens", Error: err, }) if err != nil { server.ThrowFatal(w, err) } return } tx.Commit() w.WriteHeader(http.StatusOK) }, ) }