add optional prefix to url
This commit is contained in:
@@ -84,7 +84,7 @@ func (s *Server) CSRFRequire() gin.HandlerFunc {
|
||||
func (s *Server) RequireAuth() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
if _, exists := c.Get("user_id"); !exists {
|
||||
c.Redirect(http.StatusFound, "/editor/login")
|
||||
c.Redirect(http.StatusFound, s.config.URLPrefix+"/editor/login")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
@@ -96,7 +96,7 @@ func (s *Server) RequireAuth() gin.HandlerFunc {
|
||||
func (s *Server) RequireAdmin() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
if _, exists := c.Get("user_id"); !exists {
|
||||
c.Redirect(http.StatusFound, "/editor/login")
|
||||
c.Redirect(http.StatusFound, s.config.URLPrefix+"/editor/login")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -85,28 +85,30 @@ func (s *Server) Start() error {
|
||||
|
||||
func (s *Server) setupRoutes() {
|
||||
h := handlers.New(s.config, s.store, s.auth)
|
||||
// Group all routes under optional URL prefix
|
||||
r := s.router.Group(s.config.URLPrefix)
|
||||
|
||||
// Main routes
|
||||
s.router.GET("/", h.IndexHandler)
|
||||
s.router.GET("/folder/*path", h.FolderHandler)
|
||||
s.router.GET("/note/*path", h.NoteHandler)
|
||||
r.GET("/", h.IndexHandler)
|
||||
r.GET("/folder/*path", h.FolderHandler)
|
||||
r.GET("/note/*path", h.NoteHandler)
|
||||
|
||||
// File serving routes
|
||||
s.router.GET("/serve_attached_image/*path", h.ServeAttachedImageHandler)
|
||||
s.router.GET("/serve_stored_image/:filename", h.ServeStoredImageHandler)
|
||||
s.router.GET("/download/*path", h.DownloadHandler)
|
||||
s.router.GET("/view_text/*path", h.ViewTextHandler)
|
||||
r.GET("/serve_attached_image/*path", h.ServeAttachedImageHandler)
|
||||
r.GET("/serve_stored_image/:filename", h.ServeStoredImageHandler)
|
||||
r.GET("/download/*path", h.DownloadHandler)
|
||||
r.GET("/view_text/*path", h.ViewTextHandler)
|
||||
|
||||
// Auth routes
|
||||
s.router.GET("/editor/login", h.LoginPage)
|
||||
s.router.POST("/editor/login", s.CSRFRequire(), h.LoginPost)
|
||||
s.router.POST("/editor/logout", s.RequireAuth(), s.CSRFRequire(), h.LogoutPost)
|
||||
r.GET("/editor/login", h.LoginPage)
|
||||
r.POST("/editor/login", s.CSRFRequire(), h.LoginPost)
|
||||
r.POST("/editor/logout", s.RequireAuth(), s.CSRFRequire(), h.LogoutPost)
|
||||
// MFA challenge routes (no auth yet, but CSRF)
|
||||
s.router.GET("/editor/mfa", s.CSRFRequire(), h.MFALoginPage)
|
||||
s.router.POST("/editor/mfa", s.CSRFRequire(), h.MFALoginVerify)
|
||||
r.GET("/editor/mfa", s.CSRFRequire(), h.MFALoginPage)
|
||||
r.POST("/editor/mfa", s.CSRFRequire(), h.MFALoginVerify)
|
||||
|
||||
// New /editor group protected by auth + CSRF
|
||||
editor := s.router.Group("/editor", s.RequireAuth(), s.CSRFRequire())
|
||||
editor := r.Group("/editor", s.RequireAuth(), s.CSRFRequire())
|
||||
{
|
||||
editor.GET("/create", h.CreateNotePageHandler)
|
||||
editor.POST("/create", h.CreateNoteHandler)
|
||||
@@ -171,8 +173,8 @@ func (s *Server) setupRoutes() {
|
||||
}
|
||||
|
||||
// API routes
|
||||
s.router.GET("/api/tree", h.TreeAPIHandler)
|
||||
s.router.GET("/api/search", h.SearchHandler)
|
||||
r.GET("/api/tree", h.TreeAPIHandler)
|
||||
r.GET("/api/search", h.SearchHandler)
|
||||
}
|
||||
|
||||
func (s *Server) setupStaticFiles() {
|
||||
@@ -181,9 +183,9 @@ func (s *Server) setupStaticFiles() {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
s.router.StaticFS("/static", http.FS(sub))
|
||||
s.router.StaticFS(s.config.URLPrefix+"/static", http.FS(sub))
|
||||
// Favicon from same sub FS
|
||||
s.router.StaticFileFS("/favicon.ico", "favicon.ico", http.FS(sub))
|
||||
s.router.StaticFileFS(s.config.URLPrefix+"/favicon.ico", "favicon.ico", http.FS(sub))
|
||||
}
|
||||
|
||||
func (s *Server) setupTemplates() {
|
||||
@@ -192,6 +194,24 @@ func (s *Server) setupTemplates() {
|
||||
"formatSize": utils.FormatFileSize,
|
||||
"formatTime": utils.FormatTime,
|
||||
"join": strings.Join,
|
||||
// base returns the configured URL prefix ("" for root)
|
||||
"base": func() string { return s.config.URLPrefix },
|
||||
// url joins the base with the given path ensuring single slash
|
||||
"url": func(p string) string {
|
||||
bp := s.config.URLPrefix
|
||||
if bp == "" {
|
||||
if p == "" { return "" }
|
||||
if strings.HasPrefix(p, "/") { return p }
|
||||
return "/" + p
|
||||
}
|
||||
if p == "" || p == "/" {
|
||||
return bp + "/"
|
||||
}
|
||||
if strings.HasPrefix(p, "/") {
|
||||
return bp + p
|
||||
}
|
||||
return bp + "/" + p
|
||||
},
|
||||
"contains": func(slice []string, item string) bool {
|
||||
for _, s := range slice {
|
||||
if s == item {
|
||||
|
||||
Reference in New Issue
Block a user