A fresh session lands on the list, not the bill
auth's SignedInPath defaults to "/", so completing the Keymail ceremony dropped an admin back on the public page they started from. Signing in here has exactly one purpose.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2 files changed,
+32
−2
internal/movement/admin.go+6 −2internal/movementtest/admin_test.go+26 −0
diff --git a/internal/movement/admin.go b/internal/movement/admin.go| index c70c9fb..b8cc4f7 100644 |
| --- a/internal/movement/admin.go |
| +++ b/internal/movement/admin.go |
| @@ -41,8 +41,12 @@ func (a *app) mountAdmin(r chi.Router) error { |
| Mailer: a.mailer, |
| Authorize: a.env.IsAdmin, |
| SigninPath: "/signin", |
| - SessionTTL: adminSessionTTL, |
| - Logger: slogFor(), |
| + // A fresh session lands on the list, not on the bill. Signing in here |
| + // has exactly one purpose, and the default "/" sends an admin who |
| + // just authenticated back to the public page they came from. |
| + SignedInPath: "/admin", |
| + SessionTTL: adminSessionTTL, |
| + Logger: slogFor(), |
| }) |
| if err != nil { |
| return err |
diff --git a/internal/movementtest/admin_test.go b/internal/movementtest/admin_test.go| index ffb713b..56f9339 100644 |
| --- a/internal/movementtest/admin_test.go |
| +++ b/internal/movementtest/admin_test.go |
| @@ -273,3 +273,29 @@ func TestRemovedAdminLosesAccessOnTheNextRequest(t *testing.T) { |
| t.Error("a removed admin still reached /admin with their old session") |
| } |
| } |
| + |
| +// Signing in has exactly one purpose here, so a fresh session lands on the |
| +// list. auth's default is "/", which would send an admin who has just |
| +// authenticated back to the public bill they started from. |
| +func TestSigningInLandsOnTheAdminList(t *testing.T) { |
| + h := newAdminApp(t) |
| + |
| + post(t, h, "/signin", url.Values{"address": {adminAddr}}) |
| + body := h.Mail.waitForMailTo(t, adminAddr, 1) |
| + link := anyLink.FindString(body) |
| + if link == "" { |
| + t.Fatalf("no sign-in link in the message:\n%s", body) |
| + } |
| + u, err := url.Parse(link) |
| + if err != nil { |
| + t.Fatal(err) |
| + } |
| + |
| + req := httptest.NewRequest(http.MethodGet, u.RequestURI(), nil) |
| + rec := httptest.NewRecorder() |
| + h.ServeHTTP(rec, req) |
| + |
| + if got := rec.Header().Get("Location"); got != "/admin" { |
| + t.Errorf("a fresh session landed on %q, want /admin", got) |
| + } |
| +} |