oficina / sheets Public

Clone
git clone https://amadan.net/oficina/sheets

Plain git — no account needed to clone.

Download

Download this file

1package sheets
2
3import (
4 "net/http"
5
6 "amadan.net/oficina/home/connect"
7)
8
9// The root page is the anonymous entry page, and nothing else.
10//
11// It used to have a signed-in state too, and that state was the whole
12// point of it: a magic link lands here, so if the page could not say
13// "you are signed in, as this address", then a successful sign-in and a
14// silently failed one looked identical to the person who clicked. That
15// is exactly what happened the first time a link was clicked here —
16// auth's SignedInPath defaults to "/", and this page told the arriving
17// user there was nothing to reach at this address.
18//
19// The fix at the time was a line naming you and a button reading "Open
20// your sheets", because /sheets did not exist yet. Once it did, that
21// state was a page whose entire content was a link to the next page,
22// and the layout's account menu names you on every screen anyway. So
23// the signed-in half is a redirect now, and the original requirement is
24// met better: you land on your sheets, which could not be mistaken for
25// a failed sign-in.
26//
27// Both halves of the hop are closed — auth is configured with
28// SignedInPath "/sheets" so a fresh click never comes through here at
29// all, and this redirect covers somebody who later types the bare
30// address. Neither alone is enough.
31//
32// With Home configured the signed-out half goes too: "/" 303s to
33// /signin, which starts the Home exchange (Home #74, decision 2). That is
34// what the app switcher's single-team hop now lands on — Home sends a
35// person to the team instance's root rather than to /auth/start — and a
36// landing page there would leave them one click short of the sign-in the
37// hop used to run for them. Docs and Calendar already answer their root
38// this way. Standalone keeps the landing page: there is no Home to hand
39// off to, and it is where a stranger learns what this instance is.
40//
41// With Home, "/" goes through homeRequire, the guard every signed-in page
42// uses, rather than a bare identity check. A Home session whose member
43// lost admission is refused by identity but is still a live cookie, and
44// connect's /signin skips the form for a live cookie: redirecting such a
45// person straight to /signin sent them back here, forever (Astra, #39).
46// The guard ends that session first, keeps its 503 for a storage failure,
47// and sends a signed-out visitor to /signin?return_to=%2F.
48func (a *App) handleIndex(w http.ResponseWriter, r *http.Request) {
49 if a.home != nil {
50 a.homeRequire(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
51 http.Redirect(w, r, "/sheets", http.StatusSeeOther)
52 })).ServeHTTP(w, r)
53 return
54 }
55 if _, ok := a.identity(r); ok {
56 http.Redirect(w, r, "/sheets", http.StatusSeeOther)
57 return
58 }
59 a.render(w, r, "index", frame{}, http.StatusOK, nil)
60}
61
62// identity returns the signed-in address, if any. A nil auth (tests)
63// simply has no session.
64func (a *App) identity(r *http.Request) (string, bool) {
65 if a.home != nil {
66 s, ok := a.homeSessions.From(r)
67 if !ok {
68 return "", false
69 }
70 if s.Method == connect.HomeMethod {
71 p, err := a.home.ResolveSession(r)
72 return p.Label, err == nil
73 }
74 }
75 if a.auth == nil {
76 return "", false
77 }
78 id, ok := a.auth.SessionFrom(r)
79 if !ok || string(id.Method) == connect.HomeMethod {
80 return "", false
81 }
82 return id.Address, true
83}
84