forked from tangled.org/core
this repo has no description

appview/oauth: return to original page after login-block

when attempting to do an authorized request while logged-out, the auth
middleware boots the user to the login page. this page now keeps track
of the 'Referer' in the oauth request. once the oauth callback is
complete, the user is sent back to the page they came from.

Signed-off-by: oppiliappan <me@oppi.li>

Changed files
+26 -6
appview
cache
session
middleware
oauth
pages
templates
user
+1
appview/cache/session/store.go
···
PkceVerifier string
DpopAuthserverNonce string
DpopPrivateJwk string
}
type SessionStore struct {
···
PkceVerifier string
DpopAuthserverNonce string
DpopPrivateJwk string
+
ReturnUrl string
}
type SessionStore struct {
+10 -2
appview/middleware/middleware.go
···
"fmt"
"log"
"net/http"
"slices"
"strconv"
"strings"
···
func AuthMiddleware(a *oauth.OAuth) middlewareFunc {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
redirectFunc := func(w http.ResponseWriter, r *http.Request) {
-
http.Redirect(w, r, "/login", http.StatusTemporaryRedirect)
}
if r.Header.Get("HX-Request") == "true" {
redirectFunc = func(w http.ResponseWriter, _ *http.Request) {
-
w.Header().Set("HX-Redirect", "/login")
w.WriteHeader(http.StatusOK)
}
}
···
"fmt"
"log"
"net/http"
+
"net/url"
"slices"
"strconv"
"strings"
···
func AuthMiddleware(a *oauth.OAuth) middlewareFunc {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+
returnURL := "/"
+
if u, err := url.Parse(r.Header.Get("Referer")); err == nil {
+
returnURL = u.RequestURI()
+
}
+
+
loginURL := fmt.Sprintf("/login?return_url=%s", url.QueryEscape(returnURL))
+
redirectFunc := func(w http.ResponseWriter, r *http.Request) {
+
http.Redirect(w, r, loginURL, http.StatusTemporaryRedirect)
}
if r.Header.Get("HX-Request") == "true" {
redirectFunc = func(w http.ResponseWriter, _ *http.Request) {
+
w.Header().Set("HX-Redirect", loginURL)
w.WriteHeader(http.StatusOK)
}
}
+11 -2
appview/oauth/handler/handler.go
···
func (o *OAuthHandler) login(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
-
o.pages.Login(w, pages.LoginParams{})
case http.MethodPost:
handle := r.FormValue("handle")
···
DpopAuthserverNonce: parResp.DpopAuthserverNonce,
DpopPrivateJwk: string(dpopKeyJson),
State: parResp.State,
})
if err != nil {
log.Println("failed to save oauth request:", err)
···
}
}
-
http.Redirect(w, r, "/", http.StatusFound)
}
func (o *OAuthHandler) logout(w http.ResponseWriter, r *http.Request) {
···
func (o *OAuthHandler) login(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
+
returnURL := r.URL.Query().Get("return_url")
+
o.pages.Login(w, pages.LoginParams{
+
ReturnUrl: returnURL,
+
})
case http.MethodPost:
handle := r.FormValue("handle")
···
DpopAuthserverNonce: parResp.DpopAuthserverNonce,
DpopPrivateJwk: string(dpopKeyJson),
State: parResp.State,
+
ReturnUrl: r.FormValue("return_url"),
})
if err != nil {
log.Println("failed to save oauth request:", err)
···
}
}
+
returnUrl := oauthRequest.ReturnUrl
+
if returnUrl == "" {
+
returnUrl = "/"
+
}
+
+
http.Redirect(w, r, returnUrl, http.StatusFound)
}
func (o *OAuthHandler) logout(w http.ResponseWriter, r *http.Request) {
+2 -2
appview/oauth/oauth.go
···
if err != nil {
return nil, false, fmt.Errorf("error parsing expiry time: %w", err)
}
-
if expiry.Sub(time.Now()) <= 5*time.Minute {
privateJwk, err := helpers.ParseJWKFromBytes([]byte(session.DpopPrivateJwk))
if err != nil {
return nil, false, err
···
redirectURIs := makeRedirectURIs(clientURI)
if o.config.Core.Dev {
-
clientURI = fmt.Sprintf("http://127.0.0.1:3000")
redirectURIs = makeRedirectURIs(clientURI)
query := url.Values{}
···
if err != nil {
return nil, false, fmt.Errorf("error parsing expiry time: %w", err)
}
+
if time.Until(expiry) <= 5*time.Minute {
privateJwk, err := helpers.ParseJWKFromBytes([]byte(session.DpopPrivateJwk))
if err != nil {
return nil, false, err
···
redirectURIs := makeRedirectURIs(clientURI)
if o.config.Core.Dev {
+
clientURI = "http://127.0.0.1:3000"
redirectURIs = makeRedirectURIs(clientURI)
query := url.Values{}
+1
appview/pages/pages.go
···
}
type LoginParams struct {
}
func (p *Pages) Login(w io.Writer, params LoginParams) error {
···
}
type LoginParams struct {
+
ReturnUrl string
}
func (p *Pages) Login(w io.Writer, params LoginParams) error {
+1
appview/pages/templates/user/login.html
···
your Tangled (<code>.tngl.sh</code>) or <a href="https://bsky.app">Bluesky</a> (<code>.bsky.social</code>) account.
</span>
</div>
<button
class="btn w-full my-2 mt-6 text-base "
···
your Tangled (<code>.tngl.sh</code>) or <a href="https://bsky.app">Bluesky</a> (<code>.bsky.social</code>) account.
</span>
</div>
+
<input type="hidden" name="return_url" value="{{ .ReturnUrl }}">
<button
class="btn w-full my-2 mt-6 text-base "