website/pkg/router/router.go
Noah Petherbridge 20d04fc370 Admin Transparency Page
* Add a transparency page where regular user accounts can list the roles and
  permissions that an admin user has access to. It is available by clicking on
  the "Admin" badge on that user's profile page.
* Add additional admin scopes to lock down more functionality:
  * User feedback and reports
  * Change logs
  * User notes and admin notes
* Add friendly descriptions to what all the scopes mean in practice.
* Don't show admin notification badges to admins who aren't allowed to act on
  those notifications.
* Update the admin dashboard page and documentation for admins.
2024-05-09 15:50:46 -07:00

142 lines
8.2 KiB
Go

// Package router configures web routes.
package router
import (
"net/http"
"code.nonshy.com/nonshy/website/pkg/config"
"code.nonshy.com/nonshy/website/pkg/controller/account"
"code.nonshy.com/nonshy/website/pkg/controller/admin"
"code.nonshy.com/nonshy/website/pkg/controller/api"
"code.nonshy.com/nonshy/website/pkg/controller/api/barertc"
"code.nonshy.com/nonshy/website/pkg/controller/block"
"code.nonshy.com/nonshy/website/pkg/controller/chat"
"code.nonshy.com/nonshy/website/pkg/controller/comment"
"code.nonshy.com/nonshy/website/pkg/controller/forum"
"code.nonshy.com/nonshy/website/pkg/controller/friend"
"code.nonshy.com/nonshy/website/pkg/controller/htmx"
"code.nonshy.com/nonshy/website/pkg/controller/inbox"
"code.nonshy.com/nonshy/website/pkg/controller/index"
"code.nonshy.com/nonshy/website/pkg/controller/photo"
"code.nonshy.com/nonshy/website/pkg/controller/poll"
"code.nonshy.com/nonshy/website/pkg/middleware"
nst "code.nonshy.com/nonshy/website/pkg/templates"
)
func New() http.Handler {
mux := http.NewServeMux()
// Register controller endpoints.
mux.HandleFunc("/", index.Create())
mux.HandleFunc("GET /favicon.ico", index.Favicon())
mux.HandleFunc("GET /manifest.json", index.Manifest())
mux.HandleFunc("GET /about", index.StaticTemplate("about.html")())
mux.HandleFunc("GET /features", index.StaticTemplate("features.html")())
mux.HandleFunc("GET /faq", index.StaticTemplate("faq.html")())
mux.HandleFunc("GET /tos", index.StaticTemplate("tos.html")())
mux.HandleFunc("GET /privacy", index.StaticTemplate("privacy.html")())
mux.HandleFunc("/contact", index.Contact())
mux.HandleFunc("/login", account.Login())
mux.HandleFunc("GET /logout", account.Logout())
mux.Handle("/signup", middleware.GeoGate(account.Signup()))
mux.HandleFunc("/forgot-password", account.ForgotPassword())
mux.HandleFunc("GET /settings/confirm-email", account.ConfirmEmailChange())
mux.HandleFunc("GET /markdown", index.StaticTemplate("markdown.html")())
mux.HandleFunc("GET /test/geo-gate", index.StaticTemplate("errors/geo_gate.html")())
// Login Required. Pages that non-certified users can access.
mux.Handle("/me", middleware.LoginRequired(account.Dashboard()))
mux.Handle("/settings", middleware.LoginRequired(account.Settings()))
mux.Handle("/settings/age-gate", middleware.LoginRequired(account.AgeGate()))
mux.Handle("/account/two-factor/setup", middleware.LoginRequired(account.Setup2FA()))
mux.Handle("/account/delete", middleware.LoginRequired(account.Delete()))
mux.Handle("/account/deactivate", middleware.LoginRequired(account.Deactivate()))
mux.Handle("GET /account/reactivate", middleware.LoginRequired(account.Reactivate()))
mux.Handle("GET /u/{username}", account.Profile()) // public access OK
mux.Handle("GET /u/{username}/friends", middleware.CertRequired(account.UserFriends()))
mux.Handle("GET /u/{username}/photos", middleware.LoginRequired(photo.UserPhotos()))
mux.Handle("/u/{username}/notes", middleware.LoginRequired(account.UserNotes()))
mux.Handle("/photo/upload", middleware.LoginRequired(photo.Upload()))
mux.Handle("GET /photo/view", middleware.LoginRequired(photo.View()))
mux.Handle("/photo/edit", middleware.LoginRequired(photo.Edit()))
mux.Handle("/photo/delete", middleware.LoginRequired(photo.Delete()))
mux.Handle("/photo/certification", middleware.LoginRequired(photo.Certification()))
mux.Handle("GET /photo/private", middleware.LoginRequired(photo.Private()))
mux.Handle("/photo/private/share", middleware.LoginRequired(photo.Share()))
mux.Handle("/notes/me", middleware.LoginRequired(account.MyNotes()))
mux.Handle("GET /messages", middleware.LoginRequired(inbox.Inbox()))
mux.Handle("GET /messages/read/{id}", middleware.LoginRequired(inbox.Inbox()))
mux.Handle("/messages/compose", middleware.LoginRequired(inbox.Compose()))
mux.Handle("/messages/delete", middleware.LoginRequired(inbox.Delete()))
mux.Handle("GET /friends", middleware.LoginRequired(friend.Friends()))
mux.Handle("/friends/add", middleware.LoginRequired(friend.AddFriend()))
mux.Handle("POST /users/block", middleware.LoginRequired(block.BlockUser()))
mux.Handle("GET /users/blocked", middleware.LoginRequired(block.Blocked()))
mux.Handle("GET /users/blocklist/add", middleware.LoginRequired(block.AddUser()))
mux.Handle("/comments", middleware.LoginRequired(comment.PostComment()))
mux.Handle("GET /comments/subscription", middleware.LoginRequired(comment.Subscription()))
mux.Handle("GET /admin/unimpersonate", middleware.LoginRequired(admin.Unimpersonate()))
mux.Handle("GET /inner-circle", middleware.LoginRequired(account.InnerCircle()))
mux.Handle("/inner-circle/invite", middleware.LoginRequired(account.InviteCircle()))
mux.Handle("GET /admin/transparency/{username}", middleware.LoginRequired(admin.Transparency()))
// Certification Required. Pages that only full (verified) members can access.
mux.Handle("GET /photo/gallery", middleware.CertRequired(photo.SiteGallery()))
mux.Handle("GET /members", middleware.CertRequired(account.Search()))
mux.Handle("/chat", middleware.CertRequired(chat.Landing()))
mux.Handle("GET /forum", middleware.CertRequired(forum.Landing()))
mux.Handle("/forum/post", middleware.CertRequired(forum.NewPost()))
mux.Handle("GET /forum/thread/{id}", middleware.CertRequired(forum.Thread()))
mux.Handle("GET /forum/newest", middleware.CertRequired(forum.Newest()))
mux.Handle("GET /forum/search", middleware.CertRequired(forum.Search()))
mux.Handle("GET /f/{fragment}", middleware.CertRequired(forum.Forum()))
mux.Handle("POST /poll/vote", middleware.CertRequired(poll.Vote()))
// Admin endpoints.
mux.Handle("GET /admin", middleware.AdminRequired("", admin.Dashboard()))
mux.Handle("/admin/scopes", middleware.AdminRequired("", admin.Scopes()))
mux.Handle("/admin/photo/certification", middleware.AdminRequired("", photo.AdminCertification()))
mux.Handle("/admin/feedback", middleware.AdminRequired(config.ScopeFeedbackAndReports, admin.Feedback()))
mux.Handle("/admin/user-action", middleware.AdminRequired("", admin.UserActions()))
mux.Handle("/admin/maintenance", middleware.AdminRequired(config.ScopeMaintenance, admin.Maintenance()))
mux.Handle("/forum/admin", middleware.AdminRequired(config.ScopeForumAdmin, forum.Manage()))
mux.Handle("/forum/admin/edit", middleware.AdminRequired(config.ScopeForumAdmin, forum.AddEdit()))
mux.Handle("/inner-circle/remove", middleware.LoginRequired(account.RemoveCircle()))
mux.Handle("/admin/photo/mark-explicit", middleware.AdminRequired(config.ScopePhotoModerator, admin.MarkPhotoExplicit()))
mux.Handle("GET /admin/changelog", middleware.AdminRequired(config.ScopeChangeLog, admin.ChangeLog()))
// JSON API endpoints.
mux.HandleFunc("GET /v1/version", api.Version())
mux.HandleFunc("GET /v1/users/me", api.LoginOK())
mux.HandleFunc("POST /v1/users/check-username", api.UsernameCheck())
mux.Handle("POST /v1/likes", middleware.LoginRequired(api.Likes()))
mux.Handle("GET /v1/likes/users", middleware.LoginRequired(api.WhoLikes()))
mux.Handle("POST /v1/notifications/read", middleware.LoginRequired(api.ReadNotification()))
mux.Handle("POST /v1/notifications/delete", middleware.LoginRequired(api.ClearNotification()))
mux.Handle("POST /v1/photos/mark-explicit", middleware.LoginRequired(api.MarkPhotoExplicit()))
mux.Handle("GET /v1/comment-photos/remove-orphaned", api.RemoveOrphanedCommentPhotos())
mux.Handle("POST /v1/barertc/report", barertc.Report())
mux.Handle("POST /v1/barertc/profile", barertc.Profile())
// HTMX endpoints.
mux.Handle("GET /htmx/user/profile/activity", middleware.LoginRequired(htmx.UserProfileActivityCard()))
// Redirect endpoints.
mux.Handle("GET /go/comment", middleware.LoginRequired(comment.GoToComment()))
// Static files.
mux.Handle("GET /static/", http.StripPrefix("/static/", http.FileServer(http.Dir(config.StaticPath))))
// Legacy route redirects (Go 1.22 path parameters update)
mux.Handle("GET /friends/u/{s}", nst.RedirectRoute("/u/%s/friends"))
mux.Handle("GET /photo/u/{s}", nst.RedirectRoute("/u/%s/photos"))
mux.Handle("GET /notes/u/{s}", nst.RedirectRoute("/u/%s/notes"))
// Global middlewares.
withCSRF := middleware.CSRF(mux)
withSession := middleware.Session(withCSRF)
withRecovery := middleware.Recovery(withSession)
withLogger := middleware.Logging(withRecovery)
return withLogger
}