Raw
 1package web
 2
 3import (
 4	"log/slog"
 5	"net/http"
 6
 7	"tug/internal/transport/web/text"
 8)
 9
10type Confirm struct {
11	Title         text.Key
12	Body          text.Key
13	Button        text.Key
14	Subject       Ident
15	Action        string
16	Cancel        string
17	Neutral       bool
18	Once          bool
19	Message       text.Key
20	Also          string
21	AlsoButton    text.Key
22	Refused       bool
23	Elsewhere     string
24	ElsewhereText text.Key
25}
26
27type OneTime struct {
28	Title    text.Key
29	Subject  Ident
30	Secret   Ident
31	Expires  Ident
32	Message  string
33	Groups   []Ident
34	Label    string
35	Back     string
36	BackText text.Key
37}
38
39func (k *Kit) RenderConfirm(w http.ResponseWriter, r *http.Request, c Confirm) {
40	if !relativeSameOrigin(c.Action) || !relativeSameOrigin(c.Cancel) || (c.Also != "" && !relativeSameOrigin(c.Also)) || (c.Elsewhere != "" && k.origins.allows(c.Elsewhere) != nil) {
41		slog.Error("confirm page refused: action and cancel must be same-origin paths")
42		k.renderError(w, r, http.StatusInternalServerError, text.ErrorInternalTitle, text.ErrorInternal)
43		return
44	}
45	p := k.formPage(w, r, c)
46	if c.Once {
47		p.Once = k.formNonce(r)
48	}
49	k.render(w, r, http.StatusOK, "confirm", p)
50}
51
52func (k *Kit) RenderOneTime(w http.ResponseWriter, r *http.Request, o OneTime) {
53	k.render(w, r, http.StatusOK, "onetime", k.newPage(w, r, newOneTimeView(o)))
54}
55
56func (k *Kit) SeeOther(w http.ResponseWriter, r *http.Request, path string) {
57	if !relativeSameOrigin(path) {
58		slog.Error("redirect refused: target must be a same-origin path")
59		k.renderError(w, r, http.StatusInternalServerError, text.ErrorInternalTitle, text.ErrorInternal)
60		return
61	}
62	http.Redirect(w, r, path, http.StatusSeeOther)
63}