package server import ( "fmt" "log/slog" "net/http" "strings" "shlf.space/internal/server/htmx" "shlf.space/internal/views/login" ) func (s *Server) 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") login.LoginPage(login.LoginPageParams{ ReturnUrl: returnURL, ErrorCode: errorCode, }).Render(r.Context(), w) case http.MethodPost: handle := r.FormValue("handle") returnURL := r.FormValue("return_url") // When users copy their handle from bsky.app, it tends to have these // characters around it: // // @nelind.dk: // \u202a ensures that the handle is always rendered left to right and // \u202c reverts that so the rest of the page renders however it should handle = strings.TrimPrefix(handle, "\u202a") handle = strings.TrimSuffix(handle, "\u202c") // `@` is harmless handle = strings.TrimPrefix(handle, "@") // Basic handle validation if !strings.Contains(handle, ".") { htmx.HxNotice(w, "login-msg", fmt.Sprintf("'%s' is an invalid handle. Did you mean %s.bsky.social?", handle, handle)) return } if err := s.oauth.SetAuthReturn(w, r, returnURL); err != nil { slog.Error("failed to set auth return", "err", err) } redirectURL, err := s.oauth.ClientApp.StartAuthFlow(r.Context(), handle) if err != nil { htmx.HxNotice(w, "login-msg", fmt.Sprintf("Failed to start auth flow: %v", err)) return } htmx.HxRedirect(w, http.StatusOK, redirectURL) } }