package server import ( "net/http" "strings" "github.com/go-chi/chi/v5" "shlf.space/internal/atproto" "shlf.space/internal/server/middleware" notfound "shlf.space/internal/views/not-found" ) func (s *Server) Router() http.Handler { router := chi.NewRouter() middleware := middleware.New( s.oauth, s.idResolver, ) userRouter := s.UserRouter(&middleware) standardRouter := s.StandardRouter(&middleware) router.HandleFunc("/*", func(w http.ResponseWriter, r *http.Request) { pat := chi.URLParam(r, "*") pathParts := strings.SplitN(pat, "/", 2) if len(pathParts) > 0 { firstPart := pathParts[0] // if using a DID or handle, just continue as per usual if atproto.IsDid(firstPart) || atproto.IsHandle(firstPart) { userRouter.ServeHTTP(w, r) return } // if using a handle with @, rewrite to work without @ if normalized := strings.TrimPrefix(firstPart, "@"); atproto.IsHandle(normalized) { redirectPath := strings.Join(append([]string{normalized}, pathParts[1:]...), "/") redirectURL := *r.URL redirectURL.Path = "/" + redirectPath http.Redirect(w, r, redirectURL.String(), http.StatusFound) return } } standardRouter.ServeHTTP(w, r) }) return router } func (s *Server) StandardRouter(middleware *middleware.Middleware) http.Handler { router := chi.NewRouter() router.Handle("/static/*", s.HandleStatic()) router.Get("/", s.Index) router.Get("/login", s.Login) router.Post("/login", s.Login) router.Post("/logout", s.Logout) router.Mount("/", s.oauth.Router()) return router } func (s *Server) UserRouter(middleware *middleware.Middleware) http.Handler { router := chi.NewRouter() router.With(middleware.ResolveIdent()).Route("/{user}", func(r chi.Router) { r.Get("/books", s.MyBooks) }) router.NotFound(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotFound) notfound.NotFoundPage(notfound.NotFoundParams{}).Render(r.Context(), w) }) return router }