Raw
 1package web
 2
 3import (
 4	"errors"
 5	"net/http"
 6
 7	"tug/internal/transport/web/text"
 8)
 9
10type adminPendingData struct {
11	Viewer   Ident
12	ID       string
13	Username Ident
14	Expires  Ident
15	Spent    bool
16	Message  text.Key
17}
18
19func (a *admin) pendingAccount(w http.ResponseWriter, r *http.Request) (Principal, string, AdminPendingAccount, bool) {
20	p, ok := a.kit.principal(w, r)
21	if !ok {
22		return Principal{}, "", AdminPendingAccount{}, false
23	}
24	id, ok := a.id(w, r)
25	if !ok {
26		return Principal{}, "", AdminPendingAccount{}, false
27	}
28	acct, err := a.b.PendingAccount(r.Context(), id)
29	if err != nil {
30		a.failed(w, r, "pending account", err)
31		return Principal{}, "", AdminPendingAccount{}, false
32	}
33	return p, id, acct, true
34}
35
36func (a *admin) pendingPage(w http.ResponseWriter, r *http.Request, p Principal, id string, acct AdminPendingAccount, message text.Key) {
37	if acct.Spent && message == "" {
38		message = text.AdminProblemConfirmSpent
39	}
40	a.render(w, r, http.StatusOK, "admin-user-confirm", adminPendingData{Viewer: p.Username, ID: id, Username: Ident(acct.Username), Expires: Ident(stamp(acct.ExpiresAt)), Spent: acct.Spent, Message: message})
41}
42
43func (a *admin) confirmShow(w http.ResponseWriter, r *http.Request) {
44	if p, id, acct, ok := a.pendingAccount(w, r); ok {
45		a.pendingPage(w, r, p, id, acct, "")
46	}
47}
48
49func (a *admin) confirmRun(w http.ResponseWriter, r *http.Request) {
50	p, id, acct, ok := a.pendingAccount(w, r)
51	if !ok {
52		return
53	}
54	err := a.b.ConfirmAccount(r.Context(), p.UserID, id, r.PostFormValue("code"))
55	switch {
56	case errors.Is(err, ErrAdminConfirmCode):
57		fresh, err := a.b.PendingAccount(r.Context(), id)
58		if err != nil {
59			a.failed(w, r, "pending account", err)
60			return
61		}
62		if fresh.Spent {
63			a.pendingPage(w, r, p, id, fresh, text.AdminProblemConfirmSpent)
64			return
65		}
66		a.pendingPage(w, r, p, id, fresh, text.AdminProblemConfirmCode)
67	case errors.Is(err, ErrAdminConfirmSpent):
68		acct.Spent = true
69		a.pendingPage(w, r, p, id, acct, text.AdminProblemConfirmSpent)
70	case err != nil:
71		a.failed(w, r, "confirm account", err)
72	default:
73		a.done(w, r, text.FlashAdminUserConfirmed, Ident(acct.Username), "/users/"+id)
74	}
75}