make notes api return any file (so images and etc can be sent)

This commit is contained in:
2026-01-13 12:13:20 +00:00
parent e756e160d7
commit 18c87c170b
3 changed files with 15 additions and 32 deletions

View File

@@ -2,18 +2,21 @@ package handlers
import ( import (
"net/http" "net/http"
"path/filepath"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
func (store *Store) GetNote(ctx *gin.Context) { func (store *Store) GetNoteFile(ctx *gin.Context) {
path := ctx.Param("path") path := ctx.Param("path")
note, err := store.Notes.GetNote(path) path, err := store.Notes.ParsePath(path)
if err != nil { if err != nil {
ctx.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) ctx.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
return return
} }
ctx.JSON(http.StatusOK, note) // Get the filename from path
filename := filepath.Base(path)
ctx.FileAttachment(path, filename)
} }

View File

@@ -70,7 +70,7 @@ func main() {
r.GET("/spotify/recent", store.RecentlyPlayed) r.GET("/spotify/recent", store.RecentlyPlayed)
// r.POST("/spotify", store.SendSong) // r.POST("/spotify", store.SendSong)
r.GET("/notes/*path", store.GetNote) r.GET("/notes/*path", store.GetNoteFile)
r.GET("/", func(c *gin.Context) { r.GET("/", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "Hello World"}) c.JSON(200, gin.H{"message": "Hello World"})

View File

@@ -5,19 +5,12 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"time"
) )
type NotesConfig struct { type NotesConfig struct {
Dir string Dir string
} }
type Note struct {
Filename string `json:"title"`
Contents string `json:"contents"`
LastEdited time.Time `json:"last_edited"`
}
type Notes struct { type Notes struct {
Config NotesConfig Config NotesConfig
} }
@@ -28,39 +21,26 @@ func InitNotes(config *NotesConfig) *Notes {
} }
} }
var ErrPathTraversal = errors.New("invalid path") func (notes *Notes) ParsePath(path string) (string, error) {
if path == "" {
path = "Index.md"
}
func (notes *Notes) GetNote(path string) (*Note, error) {
baseDir, err := filepath.Abs(notes.Config.Dir) baseDir, err := filepath.Abs(notes.Config.Dir)
if err != nil { if err != nil {
return nil, err return "", err
} }
fullPath := filepath.Join(baseDir, path) fullPath := filepath.Join(baseDir, path)
fullPath, err = filepath.Abs(fullPath) fullPath, err = filepath.Abs(fullPath)
if err != nil { if err != nil {
return nil, err return "", err
} }
// Enforce directory boundary // Enforce directory boundary
if !strings.HasPrefix(fullPath, baseDir+string(os.PathSeparator)) { if !strings.HasPrefix(fullPath, baseDir+string(os.PathSeparator)) {
return nil, ErrPathTraversal return "", errors.New("Invalid path")
} }
fullPath += ".md" return fullPath, nil
data, err := os.ReadFile(fullPath)
if err != nil {
return nil, err
}
info, err := os.Stat(fullPath)
if err != nil {
return nil, err
}
return &Note{
Filename: info.Name(),
Contents: string(data),
LastEdited: info.ModTime(),
}, nil
} }