forked from tangled.org/core
this repo has no description
1package state 2 3import ( 4 "net/http" 5 "strings" 6 7 "github.com/go-chi/chi/v5" 8 "github.com/gorilla/sessions" 9 "tangled.sh/tangled.sh/core/appview/issues" 10 "tangled.sh/tangled.sh/core/appview/knots" 11 "tangled.sh/tangled.sh/core/appview/middleware" 12 oauthhandler "tangled.sh/tangled.sh/core/appview/oauth/handler" 13 "tangled.sh/tangled.sh/core/appview/pipelines" 14 "tangled.sh/tangled.sh/core/appview/pulls" 15 "tangled.sh/tangled.sh/core/appview/repo" 16 "tangled.sh/tangled.sh/core/appview/settings" 17 "tangled.sh/tangled.sh/core/appview/signup" 18 "tangled.sh/tangled.sh/core/appview/spindles" 19 "tangled.sh/tangled.sh/core/appview/state/userutil" 20 avstrings "tangled.sh/tangled.sh/core/appview/strings" 21 "tangled.sh/tangled.sh/core/log" 22) 23 24func (s *State) Router() http.Handler { 25 router := chi.NewRouter() 26 middleware := middleware.New( 27 s.oauth, 28 s.db, 29 s.enforcer, 30 s.repoResolver, 31 s.idResolver, 32 s.pages, 33 ) 34 35 router.Get("/favicon.svg", s.Favicon) 36 router.Get("/favicon.ico", s.Favicon) 37 38 router.HandleFunc("/*", func(w http.ResponseWriter, r *http.Request) { 39 pat := chi.URLParam(r, "*") 40 if strings.HasPrefix(pat, "did:") || strings.HasPrefix(pat, "@") { 41 s.UserRouter(&middleware).ServeHTTP(w, r) 42 } else { 43 // Check if the first path element is a valid handle without '@' or a flattened DID 44 pathParts := strings.SplitN(pat, "/", 2) 45 if len(pathParts) > 0 { 46 if userutil.IsHandleNoAt(pathParts[0]) { 47 // Redirect to the same path but with '@' prefixed to the handle 48 redirectPath := "@" + pat 49 http.Redirect(w, r, "/"+redirectPath, http.StatusFound) 50 return 51 } else if userutil.IsFlattenedDid(pathParts[0]) { 52 // Redirect to the unflattened DID version 53 unflattenedDid := userutil.UnflattenDid(pathParts[0]) 54 var redirectPath string 55 if len(pathParts) > 1 { 56 redirectPath = unflattenedDid + "/" + pathParts[1] 57 } else { 58 redirectPath = unflattenedDid 59 } 60 http.Redirect(w, r, "/"+redirectPath, http.StatusFound) 61 return 62 } 63 } 64 s.StandardRouter(&middleware).ServeHTTP(w, r) 65 } 66 }) 67 68 return router 69} 70 71func (s *State) UserRouter(mw *middleware.Middleware) http.Handler { 72 r := chi.NewRouter() 73 74 r.With(mw.ResolveIdent()).Route("/{user}", func(r chi.Router) { 75 r.Get("/", s.Profile) 76 r.Get("/feed.atom", s.AtomFeedPage) 77 78 r.With(mw.ResolveRepo()).Route("/{repo}", func(r chi.Router) { 79 r.Use(mw.GoImport()) 80 81 r.Mount("/", s.RepoRouter(mw)) 82 r.Mount("/issues", s.IssuesRouter(mw)) 83 r.Mount("/pulls", s.PullsRouter(mw)) 84 r.Mount("/pipelines", s.PipelinesRouter(mw)) 85 86 // These routes get proxied to the knot 87 r.Get("/info/refs", s.InfoRefs) 88 r.Post("/git-upload-pack", s.UploadPack) 89 r.Post("/git-receive-pack", s.ReceivePack) 90 91 }) 92 }) 93 94 r.NotFound(func(w http.ResponseWriter, r *http.Request) { 95 s.pages.Error404(w) 96 }) 97 98 return r 99} 100 101func (s *State) StandardRouter(mw *middleware.Middleware) http.Handler { 102 r := chi.NewRouter() 103 104 r.Handle("/static/*", s.pages.Static()) 105 106 r.Get("/", s.Timeline) 107 108 r.Route("/repo", func(r chi.Router) { 109 r.Route("/new", func(r chi.Router) { 110 r.Use(middleware.AuthMiddleware(s.oauth)) 111 r.Get("/", s.NewRepo) 112 r.Post("/", s.NewRepo) 113 }) 114 // r.Post("/import", s.ImportRepo) 115 }) 116 117 r.With(middleware.AuthMiddleware(s.oauth)).Route("/follow", func(r chi.Router) { 118 r.Post("/", s.Follow) 119 r.Delete("/", s.Follow) 120 }) 121 122 r.With(middleware.AuthMiddleware(s.oauth)).Route("/star", func(r chi.Router) { 123 r.Post("/", s.Star) 124 r.Delete("/", s.Star) 125 }) 126 127 r.With(middleware.AuthMiddleware(s.oauth)).Route("/react", func(r chi.Router) { 128 r.Post("/", s.React) 129 r.Delete("/", s.React) 130 }) 131 132 r.Route("/profile", func(r chi.Router) { 133 r.Use(middleware.AuthMiddleware(s.oauth)) 134 r.Get("/edit-bio", s.EditBioFragment) 135 r.Get("/edit-pins", s.EditPinsFragment) 136 r.Post("/bio", s.UpdateProfileBio) 137 r.Post("/pins", s.UpdateProfilePins) 138 }) 139 140 r.Mount("/settings", s.SettingsRouter()) 141 r.Mount("/strings", s.StringsRouter(mw)) 142 r.Mount("/knots", s.KnotsRouter(mw)) 143 r.Mount("/spindles", s.SpindlesRouter()) 144 r.Mount("/signup", s.SignupRouter()) 145 r.Mount("/", s.OAuthRouter()) 146 147 r.Get("/keys/{user}", s.Keys) 148 r.Get("/terms", s.TermsOfService) 149 r.Get("/privacy", s.PrivacyPolicy) 150 151 r.NotFound(func(w http.ResponseWriter, r *http.Request) { 152 s.pages.Error404(w) 153 }) 154 return r 155} 156 157func (s *State) OAuthRouter() http.Handler { 158 store := sessions.NewCookieStore([]byte(s.config.Core.CookieSecret)) 159 oauth := oauthhandler.New(s.config, s.pages, s.idResolver, s.db, s.sess, store, s.oauth, s.enforcer, s.posthog) 160 return oauth.Router() 161} 162 163func (s *State) SettingsRouter() http.Handler { 164 settings := &settings.Settings{ 165 Db: s.db, 166 OAuth: s.oauth, 167 Pages: s.pages, 168 Config: s.config, 169 } 170 171 return settings.Router() 172} 173 174func (s *State) SpindlesRouter() http.Handler { 175 logger := log.New("spindles") 176 177 spindles := &spindles.Spindles{ 178 Db: s.db, 179 OAuth: s.oauth, 180 Pages: s.pages, 181 Config: s.config, 182 Enforcer: s.enforcer, 183 IdResolver: s.idResolver, 184 Logger: logger, 185 } 186 187 return spindles.Router() 188} 189 190func (s *State) KnotsRouter(mw *middleware.Middleware) http.Handler { 191 logger := log.New("knots") 192 193 knots := &knots.Knots{ 194 Db: s.db, 195 OAuth: s.oauth, 196 Pages: s.pages, 197 Config: s.config, 198 Enforcer: s.enforcer, 199 IdResolver: s.idResolver, 200 Knotstream: s.knotstream, 201 Logger: logger, 202 } 203 204 return knots.Router(mw) 205} 206 207func (s *State) StringsRouter(mw *middleware.Middleware) http.Handler { 208 logger := log.New("strings") 209 210 strs := &avstrings.Strings{ 211 Db: s.db, 212 OAuth: s.oauth, 213 Pages: s.pages, 214 Config: s.config, 215 Enforcer: s.enforcer, 216 IdResolver: s.idResolver, 217 Knotstream: s.knotstream, 218 Logger: logger, 219 } 220 221 return strs.Router(mw) 222} 223 224func (s *State) IssuesRouter(mw *middleware.Middleware) http.Handler { 225 issues := issues.New(s.oauth, s.repoResolver, s.pages, s.idResolver, s.db, s.config, s.notifier) 226 return issues.Router(mw) 227} 228 229func (s *State) PullsRouter(mw *middleware.Middleware) http.Handler { 230 pulls := pulls.New(s.oauth, s.repoResolver, s.pages, s.idResolver, s.db, s.config, s.notifier) 231 return pulls.Router(mw) 232} 233 234func (s *State) RepoRouter(mw *middleware.Middleware) http.Handler { 235 logger := log.New("repo") 236 repo := repo.New(s.oauth, s.repoResolver, s.pages, s.spindlestream, s.idResolver, s.db, s.config, s.notifier, s.enforcer, logger) 237 return repo.Router(mw) 238} 239 240func (s *State) PipelinesRouter(mw *middleware.Middleware) http.Handler { 241 pipes := pipelines.New(s.oauth, s.repoResolver, s.pages, s.spindlestream, s.idResolver, s.db, s.config, s.enforcer) 242 return pipes.Router(mw) 243} 244 245func (s *State) SignupRouter() http.Handler { 246 logger := log.New("signup") 247 248 sig := signup.New(s.config, s.db, s.posthog, s.idResolver, s.pages, logger) 249 return sig.Router() 250}