admin account/TOTP fixes

This commit is contained in:
ari melody 2025-10-21 21:00:54 +01:00
parent e5689ce950
commit ad50b9e4fa
Signed by: ari
GPG key ID: CF99829C92678188
14 changed files with 67 additions and 43 deletions

View file

@ -20,7 +20,7 @@ func accountHandler(app *model.AppState) http.Handler {
mux.Handle("/account/totp-setup", totpSetupHandler(app))
mux.Handle("/account/totp-confirm", totpConfirmHandler(app))
mux.Handle("/account/totp-delete/", http.StripPrefix("/totp-delete", totpDeleteHandler(app)))
mux.Handle("/account/totp-delete", totpDeleteHandler(app))
mux.Handle("/account/password", changePasswordHandler(app))
mux.Handle("/account/delete", deleteAccountHandler(app))
@ -266,11 +266,6 @@ func totpConfirmHandler(app *model.AppState) http.Handler {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
code := r.FormValue("totp")
if len(code) != controller.TOTP_CODE_LENGTH {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
totp, err := controller.GetTOTP(app.DB, session.Account.ID, name)
if err != nil {
@ -290,23 +285,22 @@ func totpConfirmHandler(app *model.AppState) http.Handler {
fmt.Fprintf(os.Stderr, "WARN: Failed to generate TOTP QR code: %v\n", err)
}
code := r.FormValue("totp")
confirmCode := controller.GenerateTOTP(totp.Secret, 0)
if code != confirmCode {
confirmCodeOffset := controller.GenerateTOTP(totp.Secret, 1)
if code != confirmCodeOffset {
session.Error = sql.NullString{ Valid: true, String: "Incorrect TOTP code. Please try again." }
err = templates.TOTPConfirmTemplate.Execute(w, totpConfirmData{
adminPageData: adminPageData{ Path: r.URL.Path, Session: session },
TOTP: totp,
NameEscaped: url.PathEscape(totp.Name),
QRBase64Image: qrBase64Image,
})
if err != nil {
fmt.Fprintf(os.Stderr, "WARN: Failed to render TOTP setup page: %v\n", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}
return
confirmCodeOffset := controller.GenerateTOTP(totp.Secret, 1)
if len(code) != controller.TOTP_CODE_LENGTH || (code != confirmCode && code != confirmCodeOffset) {
session.Error = sql.NullString{ Valid: true, String: "Incorrect TOTP code. Please try again." }
err = templates.TOTPConfirmTemplate.Execute(w, totpConfirmData{
adminPageData: adminPageData{ Path: r.URL.Path, Session: session },
TOTP: totp,
NameEscaped: url.PathEscape(totp.Name),
QRBase64Image: qrBase64Image,
})
if err != nil {
fmt.Fprintf(os.Stderr, "WARN: Failed to render TOTP setup page: %v\n", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}
return
}
err = controller.ConfirmTOTP(app.DB, session.Account.ID, name)
@ -327,18 +321,23 @@ func totpConfirmHandler(app *model.AppState) http.Handler {
func totpDeleteHandler(app *model.AppState) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
if r.Method != http.MethodPost {
http.NotFound(w, r)
return
}
if len(r.URL.Path) < 2 {
session := r.Context().Value("session").(*model.Session)
err := r.ParseForm()
if err != nil {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
name := r.FormValue("totp-name")
if len(name) == 0 {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
name := r.URL.Path[1:]
session := r.Context().Value("session").(*model.Session)
totp, err := controller.GetTOTP(app.DB, session.Account.ID, name)
if err != nil {