feat(web): route unauthenticated root to /welcome, deep links to login
An unauthenticated visit to / now lands on the public /welcome page instead of bouncing straight to Dex. Deeper guarded paths still redirect to /auth/login so the post-login round-trip returns the visitor to the page they asked for. isPublicPath runs first, so no redirect loop. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -161,11 +161,11 @@ func (d *DexAuth) Middleware(h http.Handler) http.Handler {
|
|||||||
}
|
}
|
||||||
sid, ok := d.sessionID(r)
|
sid, ok := d.sessionID(r)
|
||||||
if !ok {
|
if !ok {
|
||||||
d.redirectToLogin(w, r)
|
d.redirectUnauthenticated(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if _, ok := d.sessions.get(sid, d.now()); !ok {
|
if _, ok := d.sessions.get(sid, d.now()); !ok {
|
||||||
d.redirectToLogin(w, r)
|
d.redirectUnauthenticated(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
d.sessions.refresh(sid, d.now().Add(d.sessionTTL)) // sliding refresh
|
d.sessions.refresh(sid, d.now().Add(d.sessionTTL)) // sliding refresh
|
||||||
@@ -269,6 +269,18 @@ func (d *DexAuth) handleLogout(w http.ResponseWriter, r *http.Request) {
|
|||||||
http.Redirect(w, r, loginPath, http.StatusFound)
|
http.Redirect(w, r, loginPath, http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// redirectUnauthenticated sends an unauthenticated visitor somewhere useful: the
|
||||||
|
// bare root goes to the public landing page (/welcome), any deeper guarded path
|
||||||
|
// goes to login so the post-login round-trip can return them to it. isPublicPath
|
||||||
|
// has already let /welcome and /auth/* through, so this never loops.
|
||||||
|
func (d *DexAuth) redirectUnauthenticated(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.URL.Path == "/" {
|
||||||
|
http.Redirect(w, r, "/welcome", http.StatusFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
d.redirectToLogin(w, r)
|
||||||
|
}
|
||||||
|
|
||||||
func (d *DexAuth) redirectToLogin(w http.ResponseWriter, r *http.Request) {
|
func (d *DexAuth) redirectToLogin(w http.ResponseWriter, r *http.Request) {
|
||||||
http.Redirect(w, r, loginPath, http.StatusFound)
|
http.Redirect(w, r, loginPath, http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -248,9 +248,15 @@ func TestMiddlewareRedirectsUnauthenticated(t *testing.T) {
|
|||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// The bare root sends an unauthenticated visitor to the public landing page.
|
||||||
rec := httptest.NewRecorder()
|
rec := httptest.NewRecorder()
|
||||||
guarded.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/", nil))
|
guarded.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/", nil))
|
||||||
|
require.Equal(t, http.StatusFound, rec.Code)
|
||||||
|
require.Equal(t, "/welcome", rec.Header().Get("Location"))
|
||||||
|
|
||||||
|
// A deeper guarded path goes to login so the post-login round-trip returns there.
|
||||||
|
rec = httptest.NewRecorder()
|
||||||
|
guarded.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/v/some-id", nil))
|
||||||
require.Equal(t, http.StatusFound, rec.Code)
|
require.Equal(t, http.StatusFound, rec.Code)
|
||||||
require.Equal(t, "/auth/login", rec.Header().Get("Location"))
|
require.Equal(t, "/auth/login", rec.Header().Get("Location"))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user