oficina / docs Public

Keep Docs signed out until Home sign-in is explicitly restarted

Paul Campbell pushed by paul@keymail.dev 3ed76656449e3ed59afed7a828ba7e35c9ec87d7 parent e9f8afc
5 files changed, +31 −2
  • internal/docs/app.go +5 −1
  • internal/docs/home_render.go +3 −0
  • internal/docs/home_router_integration_test.go +5 −1
  • internal/docs/home_routes.go +14 −0
  • internal/docs/render.go +4 −0

CI passed — run details

diff --git a/internal/docs/app.go b/internal/docs/app.go
index 35ba45c..b96c866 100644
--- a/internal/docs/app.go
+++ b/internal/docs/app.go
@@ -499,7 +499,11 @@ func New(cfg Config) (*App, error) {
// sits above the RequireSession group rather than inside it with an
// exception carved into the middleware.
r.Get("/p/{token}", h.publicShow)
- r.Post("/signout", authPlugin.Signout)
+ if home == nil {
+ r.Post("/signout", authPlugin.Signout)
+ } else {
+ r.Post("/signout", home.signout)
+ }
// staticHandler (assets.go) composes the committed editor bundle
// with render.assets.Handler()'s vendored design-system tree —
// both live under this one URL prefix, so one composed handler,
diff --git a/internal/docs/home_render.go b/internal/docs/home_render.go
index 3577c7b..9c891da 100644
--- a/internal/docs/home_render.go
+++ b/internal/docs/home_render.go
@@ -24,6 +24,9 @@ func (rd *renderer) homeLink(w http.ResponseWriter, r *http.Request, state, addr
case "unknown":
page.Action = "/signin/local"
page.ActionLabel = rastrillo.T(r, key+"local_action")
+ case "signedout":
+ page.Action = "/signin"
+ page.ActionLabel = rastrillo.T(r, key+"signedout_action")
case "success":
page.Action = "/"
page.ActionLabel = rastrillo.T(r, key+"documents_action")
diff --git a/internal/docs/home_router_integration_test.go b/internal/docs/home_router_integration_test.go
index dacda5a..59ec79f 100644
--- a/internal/docs/home_router_integration_test.go
+++ b/internal/docs/home_router_integration_test.go
@@ -265,7 +265,11 @@ func TestHomeRouterExistingAccountRoundTripPreservesOwnedAndSharedContent(t *tes
if rec := b.do("GET", resource, ""); rec.Code != 200 {
t.Fatal("linked local account cannot read original document", rec.Code)
}
- routerRedirect(t, b.do("POST", "/signout", ""), "/signin")
+ routerRedirect(t, b.do("POST", "/signout", ""), "/signed-out")
+ signedOut := b.do("GET", "/signed-out", "")
+ if signedOut.Code != http.StatusOK || signedOut.Header().Get("Location") != "" || !strings.Contains(signedOut.Body.String(), `href="/signin"`) {
+ t.Fatal("signout automatically resumed Home authentication")
+ }
if b.cookies[f.sessions.CookieName()] != nil {
t.Fatal("actual signout retained session cookie")
}
diff --git a/internal/docs/home_routes.go b/internal/docs/home_routes.go
index bae044d..01f05de 100644
--- a/internal/docs/home_routes.go
+++ b/internal/docs/home_routes.go
@@ -93,6 +93,9 @@ func localAuthGuard(home *homeRoutes, next http.HandlerFunc) http.HandlerFunc {
func (h *homeRoutes) mountPublic(r chi.Router) {
r.Get("/signin", h.signin)
+ r.Get("/signed-out", func(w http.ResponseWriter, r *http.Request) {
+ h.handlers.render.homeLink(w, r, "signedout", "", http.StatusOK)
+ })
r.Get("/signin/local", h.handlers.signin)
r.Get(localLinkCompletePath, h.navigation.Complete)
r.Get(handoff.StartPath, h.bridge.Start)
@@ -158,3 +161,14 @@ func (h *handlers) homeLinkLabel(r *http.Request) string {
}
return rastrillo.T(r, "docs.home.menu_action")
}
+
+// Docs sign-out stops here even while Home retains its own session. Returning
+// directly to /signin would immediately start another Home exchange.
+func (h *homeRoutes) signout(w http.ResponseWriter, r *http.Request) {
+ h.bridge.sessions.SignOut(w, r)
+ for _, name := range []string{homeInitCookie, homeProofCookie, localLinkNavigationCookie, homeReturnCookie, "__Host-oficina-assertion-pending", "__Host-oficina-assertion-inbox"} {
+ localNavigationCookie(w, name, "", -1)
+ }
+ w.Header().Set("Cache-Control", "no-store")
+ http.Redirect(w, r, "/signed-out", http.StatusSeeOther)
+}
diff --git a/internal/docs/render.go b/internal/docs/render.go
index 5638a1b..8dc5ac7 100644
--- a/internal/docs/render.go
+++ b/internal/docs/render.go
@@ -59,6 +59,10 @@ const (
// template or a handler), resolved through rastrillo.T at render
// time. cmd/docs/main.go wires it in as rastrillo.Options.BaseCatalog.
var Catalog = rastrillo.Catalog{
+ "docs.home.signedout_title": "Signed out of Docs",
+ "docs.home.signedout_body": "You can sign in again with Home.",
+ "docs.home.signedout_action": "Sign in with Home",
+
"docs.home.start_title": "Connect Docs to Home",
"docs.home.start_body": "Use Home to sign in to this Docs account. Your documents and sharing settings stay as they are.",
"docs.home.start_action": "Continue to Home",