diff --git a/appview/oauth/handler.go b/appview/oauth/handler.go
index 1ea04ab9..10c77b60 100644
--- a/appview/oauth/handler.go
+++ b/appview/oauth/handler.go
@@ -4,11 +4,13 @@ import (
"bytes"
"context"
"encoding/json"
+ "errors"
"fmt"
"net/http"
"slices"
"time"
+ "github.com/bluesky-social/indigo/atproto/auth/oauth"
"github.com/go-chi/chi/v5"
"github.com/lestrrat-go/jwx/v2/jwk"
"github.com/posthog/posthog-go"
@@ -58,15 +60,24 @@ func (o *OAuth) jwks(w http.ResponseWriter, r *http.Request) {
func (o *OAuth) callback(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
+ l := o.Logger.With("query", r.URL.Query())
sessData, err := o.ClientApp.ProcessCallback(ctx, r.URL.Query())
if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
+ var callbackErr *oauth.AuthRequestCallbackError
+ if errors.As(err, &callbackErr) {
+ l.Debug("callback error", "err", callbackErr)
+ http.Redirect(w, r, fmt.Sprintf("/login?error=%s", callbackErr.ErrorCode), http.StatusFound)
+ return
+ }
+ l.Error("failed to process callback", "err", err)
+ http.Redirect(w, r, "/login?error=oauth", http.StatusFound)
return
}
if err := o.SaveSession(w, r, sessData); err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
+ l.Error("failed to save session", "data", sessData, "err", err)
+ http.Redirect(w, r, "/login?error=session", http.StatusFound)
return
}
diff --git a/appview/pages/pages.go b/appview/pages/pages.go
index 296d797d..bd729f99 100644
--- a/appview/pages/pages.go
+++ b/appview/pages/pages.go
@@ -221,6 +221,7 @@ func (p *Pages) Favicon(w io.Writer) error {
type LoginParams struct {
ReturnUrl string
+ ErrorCode string
}
func (p *Pages) Login(w io.Writer, params LoginParams) error {
diff --git a/appview/pages/templates/user/login.html b/appview/pages/templates/user/login.html
index 2b9347b4..4420cdb8 100644
--- a/appview/pages/templates/user/login.html
+++ b/appview/pages/templates/user/login.html
@@ -13,7 +13,7 @@
login · tangled
-
+
{{ template "fragments/logotype" }}
@@ -21,7 +21,7 @@
tightly-knit social coding.
+ {{ if .ErrorCode }}
+
+
{{ i "circle-alert" "w-4 h-4" }}
+
+
Login error
+
+ {{ if eq .ErrorCode "access_denied" }}
+ You have not authorized the app.
+ {{ else if eq .ErrorCode "session" }}
+ Server failed to create user session.
+ {{ else }}
+ Internal Server error.
+ {{ end }}
+ Please try again.
+
+
+
+ {{ end }}
Don't have an account? Create an account on Tangled now!
diff --git a/appview/state/login.go b/appview/state/login.go
index a476cfb3..89797cb7 100644
--- a/appview/state/login.go
+++ b/appview/state/login.go
@@ -14,8 +14,10 @@ func (s *State) Login(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
returnURL := r.URL.Query().Get("return_url")
+ errorCode := r.URL.Query().Get("error")
s.pages.Login(w, pages.LoginParams{
ReturnUrl: returnURL,
+ ErrorCode: errorCode,
})
case http.MethodPost:
handle := r.FormValue("handle")