diff --git a/pkg/webui/accounts.go b/pkg/webui/accounts.go index 7ca9d39..a6aa6ce 100644 --- a/pkg/webui/accounts.go +++ b/pkg/webui/accounts.go @@ -20,7 +20,7 @@ func handleAccountsGET(db *database.DB) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { accounts, err := db.LoadAccounts() if err != nil { - errorResponse(w, http.StatusInternalServerError, err) + errorResponse(w, r, http.StatusInternalServerError, err) return } render(w, accountsTemplates, http.StatusOK, AccountsPage{ diff --git a/pkg/webui/admin.go b/pkg/webui/admin.go index 54682d7..1906b3e 100644 --- a/pkg/webui/admin.go +++ b/pkg/webui/admin.go @@ -19,7 +19,7 @@ func adminMiddleware(db *database.DB, requireLogin func(http.Handler) http.Handl return } if !account.(*model.Account).IsAdmin { - errorResponse(w, http.StatusForbidden, fmt.Errorf("Only administrators can perform this request.")) + errorResponse(w, r, http.StatusForbidden, fmt.Errorf("Only administrators can perform this request.")) return } next.ServeHTTP(w, r) diff --git a/pkg/webui/error.go b/pkg/webui/error.go index afce9a6..6e9815c 100644 --- a/pkg/webui/error.go +++ b/pkg/webui/error.go @@ -7,15 +7,15 @@ import ( var errorTemplates = template.Must(template.ParseFS(htmlFS, "html/base.html", "html/error.html")) -func errorResponse(w http.ResponseWriter, status int, err error) { +func errorResponse(w http.ResponseWriter, r *http.Request, status int, err error) { type ErrorData struct { - Page + Page *Page Err error Status int StatusText string } render(w, errorTemplates, status, &ErrorData{ - Page: Page{Title: "Error", Section: "error"}, + Page: makePage(r, &Page{Title: "Error", Section: "error"}), Err: err, Status: status, StatusText: http.StatusText(status), diff --git a/pkg/webui/index.go b/pkg/webui/index.go index 28a4964..da28318 100644 --- a/pkg/webui/index.go +++ b/pkg/webui/index.go @@ -28,7 +28,7 @@ func handleIndexGET() http.Handler { if r.URL.Path == "/" { http.Redirect(w, r, "/states", http.StatusFound) } else { - errorResponse(w, http.StatusNotFound, fmt.Errorf("Page not found")) + errorResponse(w, r, http.StatusNotFound, fmt.Errorf("Page not found")) } }) } diff --git a/pkg/webui/login.go b/pkg/webui/login.go index 18864b2..abf269b 100644 --- a/pkg/webui/login.go +++ b/pkg/webui/login.go @@ -48,14 +48,14 @@ func handleLoginPOST(db *database.DB) http.Handler { } return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { - errorResponse(w, http.StatusBadRequest, err) + errorResponse(w, r, http.StatusBadRequest, err) return } username := r.FormValue("username") password := r.FormValue("password") if username == "" || password == "" { // the webui cannot issue this - errorResponse(w, http.StatusBadRequest, fmt.Errorf("Forbidden")) + errorResponse(w, r, http.StatusBadRequest, fmt.Errorf("Forbidden")) return } if ok := validUsername.MatchString(username); !ok { @@ -64,7 +64,7 @@ func handleLoginPOST(db *database.DB) http.Handler { } account, err := db.LoadAccountByUsername(username) if err != nil { - errorResponse(w, http.StatusInternalServerError, err) + errorResponse(w, r, http.StatusInternalServerError, err) return } if account == nil || !account.CheckPassword(password) { @@ -72,12 +72,12 @@ func handleLoginPOST(db *database.DB) http.Handler { return } if err := db.TouchAccount(account); err != nil { - errorResponse(w, http.StatusInternalServerError, err) + errorResponse(w, r, http.StatusInternalServerError, err) return } sessionId, err := db.CreateSession(account) if err != nil { - errorResponse(w, http.StatusInternalServerError, err) + errorResponse(w, r, http.StatusInternalServerError, err) return } http.SetCookie(w, &http.Cookie{ @@ -105,7 +105,7 @@ func loginMiddleware(db *database.DB, requireSession func(http.Handler) http.Han } account, err := db.LoadAccountById(session.(*model.Session).AccountId) if err != nil { - errorResponse(w, http.StatusInternalServerError, err) + errorResponse(w, r, http.StatusInternalServerError, err) return } if account == nil { diff --git a/pkg/webui/logout.go b/pkg/webui/logout.go index 58e445d..b7c2bde 100644 --- a/pkg/webui/logout.go +++ b/pkg/webui/logout.go @@ -18,7 +18,7 @@ func handleLogoutGET(db *database.DB) http.Handler { session := r.Context().Value(model.SessionContextKey{}) err := db.DeleteSession(session.(*model.Session)) if err != nil { - errorResponse(w, http.StatusInternalServerError, err) + errorResponse(w, r, http.StatusInternalServerError, err) return } unsetSesssionCookie(w) diff --git a/pkg/webui/sessions.go b/pkg/webui/sessions.go index 7a2fd02..5a44ab7 100644 --- a/pkg/webui/sessions.go +++ b/pkg/webui/sessions.go @@ -17,7 +17,7 @@ func sessionsMiddleware(db *database.DB) func(http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { cookie, err := r.Cookie(cookieName) if err != nil && !errors.Is(err, http.ErrNoCookie) { - errorResponse(w, http.StatusInternalServerError, fmt.Errorf("failed to get request cookie \"%s\": %w", cookieName, err)) + errorResponse(w, r, http.StatusInternalServerError, fmt.Errorf("failed to get request cookie \"%s\": %w", cookieName, err)) return } if err == nil { @@ -26,14 +26,14 @@ func sessionsMiddleware(db *database.DB) func(http.Handler) http.Handler { } else { session, err := db.LoadSessionById(cookie.Value) if err != nil { - errorResponse(w, http.StatusInternalServerError, err) + errorResponse(w, r, http.StatusInternalServerError, err) return } if session == nil { unsetSesssionCookie(w) } else if !session.IsExpired() { if err := db.TouchSession(cookie.Value); err != nil { - errorResponse(w, http.StatusInternalServerError, err) + errorResponse(w, r, http.StatusInternalServerError, err) return } ctx := context.WithValue(r.Context(), model.SessionContextKey{}, session) diff --git a/pkg/webui/settings.go b/pkg/webui/settings.go index eb0910f..5496343 100644 --- a/pkg/webui/settings.go +++ b/pkg/webui/settings.go @@ -28,7 +28,7 @@ func handleSettingsGET(db *database.DB) http.Handler { func handleSettingsPOST(db *database.DB) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { - errorResponse(w, http.StatusBadRequest, err) + errorResponse(w, r, http.StatusBadRequest, err) return } darkMode := r.FormValue("dark-mode") @@ -38,7 +38,7 @@ func handleSettingsPOST(db *database.DB) http.Handler { account := r.Context().Value(model.AccountContextKey{}).(*model.Account) err := db.SaveAccountSettings(account, &settings) if err != nil { - errorResponse(w, http.StatusInternalServerError, err) + errorResponse(w, r, http.StatusInternalServerError, err) return } render(w, settingsTemplates, http.StatusOK, SettingsPage{ diff --git a/pkg/webui/states.go b/pkg/webui/states.go index 64b7967..63e2d0b 100644 --- a/pkg/webui/states.go +++ b/pkg/webui/states.go @@ -29,7 +29,7 @@ func handleStatesGET(db *database.DB) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { states, err := db.LoadStates() if err != nil { - errorResponse(w, http.StatusInternalServerError, err) + errorResponse(w, r, http.StatusInternalServerError, err) return } render(w, statesTemplates, http.StatusOK, StatesPage{ @@ -43,12 +43,12 @@ func handleStatesPOST(db *database.DB) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // file upload limit of 20MB if err := r.ParseMultipartForm(20 << 20); err != nil { - errorResponse(w, http.StatusBadRequest, err) + errorResponse(w, r, http.StatusBadRequest, err) return } file, _, err := r.FormFile("file") if err != nil { - errorResponse(w, http.StatusBadRequest, err) + errorResponse(w, r, http.StatusBadRequest, err) return } defer file.Close() @@ -65,18 +65,18 @@ func handleStatesPOST(db *database.DB) http.Handler { } data, err := io.ReadAll(file) if err != nil { - errorResponse(w, http.StatusBadRequest, fmt.Errorf("failed to read uploaded file: %w", err)) + errorResponse(w, r, http.StatusBadRequest, fmt.Errorf("failed to read uploaded file: %w", err)) return } fileType := http.DetectContentType(data) if fileType != "text/plain; charset=utf-8" { - errorResponse(w, http.StatusBadRequest, fmt.Errorf("invalid file type: expected \"text/plain; charset=utf-8\" but got \"%s\"", fileType)) + errorResponse(w, r, http.StatusBadRequest, fmt.Errorf("invalid file type: expected \"text/plain; charset=utf-8\" but got \"%s\"", fileType)) return } account := r.Context().Value(model.AccountContextKey{}).(*model.Account) version, err := db.CreateState(statePath, account.Id, data) if err != nil { - errorResponse(w, http.StatusInternalServerError, err) + errorResponse(w, r, http.StatusInternalServerError, err) return } if version == nil { @@ -103,22 +103,22 @@ func handleStatesIdGET(db *database.DB) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var stateId uuid.UUID if err := stateId.Parse(r.PathValue("id")); err != nil { - errorResponse(w, http.StatusBadRequest, err) + errorResponse(w, r, http.StatusBadRequest, err) return } state, err := db.LoadStateById(stateId) if err != nil { - errorResponse(w, http.StatusInternalServerError, err) + errorResponse(w, r, http.StatusInternalServerError, err) return } versions, err := db.LoadVersionsByState(state) if err != nil { - errorResponse(w, http.StatusInternalServerError, err) + errorResponse(w, r, http.StatusInternalServerError, err) return } usernames, err := db.LoadAccountUsernames() if err != nil { - errorResponse(w, http.StatusInternalServerError, err) + errorResponse(w, r, http.StatusInternalServerError, err) return } render(w, statesIdTemplate, http.StatusOK, StatesData{ diff --git a/pkg/webui/versions.go b/pkg/webui/versions.go index 8cb0a8b..4fd1c00 100644 --- a/pkg/webui/versions.go +++ b/pkg/webui/versions.go @@ -23,26 +23,26 @@ func handleVersionsGET(db *database.DB) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var versionId uuid.UUID if err := versionId.Parse(r.PathValue("id")); err != nil { - errorResponse(w, http.StatusBadRequest, err) + errorResponse(w, r, http.StatusBadRequest, err) return } version, err := db.LoadVersionById(versionId) if err != nil { - errorResponse(w, http.StatusInternalServerError, err) + errorResponse(w, r, http.StatusInternalServerError, err) return } if version == nil { - errorResponse(w, http.StatusNotFound, err) + errorResponse(w, r, http.StatusNotFound, err) return } state, err := db.LoadStateById(version.StateId) if err != nil { - errorResponse(w, http.StatusInternalServerError, err) + errorResponse(w, r, http.StatusInternalServerError, err) return } account, err := db.LoadAccountById(version.AccountId) if err != nil { - errorResponse(w, http.StatusInternalServerError, err) + errorResponse(w, r, http.StatusInternalServerError, err) return } versionData := string(version.Data[:])