From 89f4f855c8260a90eab9885de5eaca678f832831 Mon Sep 17 00:00:00 2001 From: Bram Date: Thu, 26 Feb 2026 12:58:19 +0100 Subject: [PATCH] init --- .gitignore | 4 + go.mod | 44 ++++++++ go.sum | 93 ++++++++++++++++ src/handlers.go | 80 ++++++++++++++ src/main.go | 57 ++++++++++ src/models.go | 15 +++ src/utils.go | 23 ++++ templates/admin.html | 79 ++++++++++++++ templates/download.html | 67 ++++++++++++ templates/index.html | 228 ++++++++++++++++++++++++++++++++++++++++ templates/success.html | 40 +++++++ 11 files changed, 730 insertions(+) create mode 100644 .gitignore create mode 100644 go.mod create mode 100644 go.sum create mode 100644 src/handlers.go create mode 100644 src/main.go create mode 100644 src/models.go create mode 100644 src/utils.go create mode 100644 templates/admin.html create mode 100644 templates/download.html create mode 100644 templates/index.html create mode 100644 templates/success.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..28c2ddc --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/** +files.db +build/** +uploads/** \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..2c8e839 --- /dev/null +++ b/go.mod @@ -0,0 +1,44 @@ +module Backend + +go 1.26 + +require ( + github.com/bytedance/sonic v1.14.0 // indirect + github.com/bytedance/sonic/loader v0.3.0 // indirect + github.com/cloudwego/base64x v0.1.6 // indirect + github.com/gabriel-vasile/mimetype v1.4.8 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect + github.com/gin-gonic/gin v1.11.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.27.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-yaml v1.18.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-sqlite3 v1.14.34 // indirect + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect + github.com/quic-go/qpack v0.5.1 // indirect + github.com/quic-go/quic-go v0.54.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.3.0 // indirect + go.uber.org/mock v0.5.0 // indirect + golang.org/x/arch v0.20.0 // indirect + golang.org/x/crypto v0.40.0 // indirect + golang.org/x/mod v0.25.0 // indirect + golang.org/x/net v0.42.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.35.0 // indirect + golang.org/x/text v0.27.0 // indirect + golang.org/x/tools v0.34.0 // indirect + google.golang.org/protobuf v1.36.9 // indirect + gorm.io/driver/sqlite v1.6.0 // indirect + gorm.io/gorm v1.31.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..d7dcaea --- /dev/null +++ b/go.sum @@ -0,0 +1,93 @@ +github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ= +github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA= +github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= +github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= +github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= +github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= +github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= +github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= +github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= +github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-sqlite3 v1.14.34 h1:3NtcvcUnFBPsuRcno8pUtupspG/GM+9nZ88zgJcp6Zk= +github.com/mattn/go-sqlite3 v1.14.34/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= +github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= +github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg= +github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= +golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c= +golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= +golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= +golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo= +golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= +google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= +google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ= +gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8= +gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg= +gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs= diff --git a/src/handlers.go b/src/handlers.go new file mode 100644 index 0000000..378a3e4 --- /dev/null +++ b/src/handlers.go @@ -0,0 +1,80 @@ +package main + +import ( + "fmt" + "path/filepath" + "time" + + "github.com/gin-gonic/gin" + "github.com/google/uuid" +) + +func uploadHandler(c *gin.Context) { + file, err := c.FormFile("file") + if err != nil { + c.JSON(400, gin.H{"error": "No file uploaded"}) + return + } + + id := uuid.New().String() + delID := uuid.New().String() + // Secure the filename to prevent path traversal attacks + cleanName := filepath.Base(file.Filename) + storagePath := filepath.Join("uploads", id+"_"+cleanName) + + if err := c.SaveUploadedFile(file, storagePath); err != nil { + c.JSON(500, gin.H{"error": "Failed to save file"}) + return + } + + expiry := time.Now().Add(time.Hour * 24) // Default 24h + + record := FileRecord{ + ID: id, + DeletionID: delID, + Filename: cleanName, + Path: storagePath, + ExpiresAt: expiry, + DeleteAfterDownload: c.PostForm("once") == "true", + } + + db.Create(&record) + + c.JSON(200, gin.H{ + "id": id, + "deletion_id": delID, + "filename": cleanName, + "download_url": fmt.Sprintf("/f/%s", id), + }) +} + +func downloadHandler(c *gin.Context) { + var record FileRecord + if err := db.First(&record, "id = ? AND deleted = ?", c.Param("id"), false).Error; err != nil { + c.String(404, "File not found or expired") + return + } + + if time.Now().After(record.ExpiresAt) { + performDeletion(&record) + c.String(410, "File has expired") + return + } + + c.FileAttachment(record.Path, record.Filename) + + db.Model(&record).Update("download_count", record.DownloadCount+1) + if record.DeleteAfterDownload { + performDeletion(&record) + } +} + +func deleteHandler(c *gin.Context) { + var record FileRecord + if err := db.First(&record, "deletion_id = ?", c.Param("del_id")).Error; err != nil { + c.JSON(404, gin.H{"error": "Invalid deletion ID"}) + return + } + performDeletion(&record) + c.JSON(200, gin.H{"message": "Deleted successfully"}) +} diff --git a/src/main.go b/src/main.go new file mode 100644 index 0000000..41afe57 --- /dev/null +++ b/src/main.go @@ -0,0 +1,57 @@ +package main + +import ( + "log" + "os" + + "github.com/gin-gonic/gin" + "gorm.io/driver/sqlite" + "gorm.io/gorm" +) + +var db *gorm.DB + +func main() { + _ = os.MkdirAll("uploads", 0755) + + var err error + db, err = gorm.Open(sqlite.Open("files.db"), &gorm.Config{}) + if err != nil { + log.Fatal("DB Connection failed:", err) + } + db.AutoMigrate(&FileRecord{}) + + go cleanupWorker() + + router := gin.Default() + router.MaxMultipartMemory = 100 << 20 // 100 MiB limit + router.LoadHTMLGlob("templates/*") + + // Public Routes + router.GET("/", func(c *gin.Context) { c.HTML(200, "index.html", nil) }) + router.POST("/api/upload", uploadHandler) + router.GET("/f/:id", downloadHandler) + router.DELETE("/api/file/:del_id", deleteHandler) + + // Protected Admin Routes + admin := router.Group("/admin", gin.BasicAuth(gin.Accounts{ + "admin": "password123", // CHANGE THIS + })) + + admin.GET("/", func(c *gin.Context) { + var files []FileRecord + db.Order("created_at desc").Find(&files) + c.HTML(200, "admin.html", gin.H{"Files": files}) + }) + + admin.POST("/delete/:id", func(c *gin.Context) { + var record FileRecord + if err := db.First(&record, "id = ?", c.Param("id")).Error; err == nil { + performDeletion(&record) + } + c.Redirect(303, "/admin") + }) + + log.Println("Server starting at http://localhost:8080") + router.Run(":8080") +} diff --git a/src/models.go b/src/models.go new file mode 100644 index 0000000..c385441 --- /dev/null +++ b/src/models.go @@ -0,0 +1,15 @@ +package main + +import "time" + +type FileRecord struct { + ID string `gorm:"primaryKey" json:"id"` + DeletionID string `json:"deletion_id"` + Filename string `json:"filename"` + Path string `json:"-"` + ExpiresAt time.Time `json:"expires_at"` + DeleteAfterDownload bool `json:"delete_after_download"` + DownloadCount int `json:"download_count"` + Deleted bool `json:"deleted"` + CreatedAt time.Time `json:"created_at"` +} diff --git a/src/utils.go b/src/utils.go new file mode 100644 index 0000000..73ebc5d --- /dev/null +++ b/src/utils.go @@ -0,0 +1,23 @@ +package main + +import ( + "os" + "time" +) + +func performDeletion(r *FileRecord) { + r.Deleted = true + db.Save(r) + os.Remove(r.Path) +} + +func cleanupWorker() { + for { + time.Sleep(10 * time.Minute) + var expired []FileRecord + db.Where("expires_at < ? AND deleted = ?", time.Now(), false).Find(&expired) + for _, r := range expired { + performDeletion(&r) + } + } +} diff --git a/templates/admin.html b/templates/admin.html new file mode 100644 index 0000000..ddc5cff --- /dev/null +++ b/templates/admin.html @@ -0,0 +1,79 @@ + + + + + + GhostShare | Admin + + + + + +
+
+

System Console

+ ← BACK TO UPLOADER +
+ +
+ + + + + + + + + + + + + {{range .Files}} + + + + + + + + + {{end}} + +
FilenameCreatedExpiresHitsStatusActions
{{.Filename}}{{.CreatedAt.Format "Jan 02, 15:04"}}{{.ExpiresAt.Format "Jan 02, 15:04"}}{{.DownloadCount}} {{if .DeleteAfterDownload}}(1-SHOT){{end}} + {{if .Deleted}} + REMOVED + {{else}} + LIVE + {{end}} + + {{if not .Deleted}} +
+ +
+ {{else}} + - + {{end}} +
+
+ +
+ Total Records: {{len .Files}} | Database: SQLite +
+
+ + + \ No newline at end of file diff --git a/templates/download.html b/templates/download.html new file mode 100644 index 0000000..38c0b66 --- /dev/null +++ b/templates/download.html @@ -0,0 +1,67 @@ + + + + + Uploaded | GhostShare + + + + + +
+

Upload Successful

+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ + +
+ + + + + \ No newline at end of file diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..a4d2ede --- /dev/null +++ b/templates/index.html @@ -0,0 +1,228 @@ + + + + + + GhostShare + + + + + +
+
+

Send it

+
+ +
+
+ + +
+ Click to select or drop file +
+ + + + +
+ +
+
+ + +
+ +
+ + +
+ + + +
+
+ + +
+ + + + \ No newline at end of file diff --git a/templates/success.html b/templates/success.html new file mode 100644 index 0000000..21e7c57 --- /dev/null +++ b/templates/success.html @@ -0,0 +1,40 @@ + + + + + Uploaded + + + +

File uploaded

+ +

+ Download page:
+ +

+ +

+ Direct download:
+ +

+ +

+ Delete link:
+ +

+ + + + + \ No newline at end of file