package web import ( "log/slog" "net/http" "tug/internal/transport/web/text" ) type Confirm struct { Title text.Key Body text.Key Button text.Key Subject Ident Action string Cancel string Neutral bool Once bool Message text.Key Also string AlsoButton text.Key Refused bool Elsewhere string ElsewhereText text.Key } type OneTime struct { Title text.Key Subject Ident Secret Ident Expires Ident Message string Groups []Ident Label string Back string BackText text.Key } func (k *Kit) RenderConfirm(w http.ResponseWriter, r *http.Request, c Confirm) { if !relativeSameOrigin(c.Action) || !relativeSameOrigin(c.Cancel) || (c.Also != "" && !relativeSameOrigin(c.Also)) || (c.Elsewhere != "" && k.origins.allows(c.Elsewhere) != nil) { slog.Error("confirm page refused: action and cancel must be same-origin paths") k.renderError(w, r, http.StatusInternalServerError, text.ErrorInternalTitle, text.ErrorInternal) return } p := k.formPage(w, r, c) if c.Once { p.Once = k.formNonce(r) } k.render(w, r, http.StatusOK, "confirm", p) } func (k *Kit) RenderOneTime(w http.ResponseWriter, r *http.Request, o OneTime) { k.render(w, r, http.StatusOK, "onetime", k.newPage(w, r, newOneTimeView(o))) } func (k *Kit) SeeOther(w http.ResponseWriter, r *http.Request, path string) { if !relativeSameOrigin(path) { slog.Error("redirect refused: target must be a same-origin path") k.renderError(w, r, http.StatusInternalServerError, text.ErrorInternalTitle, text.ErrorInternal) return } http.Redirect(w, r, path, http.StatusSeeOther) }