Files
send-it/src/handlers.go
2026-02-26 18:52:42 +01:00

140 lines
2.9 KiB
Go

package main
import (
"fmt"
"io"
"os"
"path/filepath"
"time"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"golang.org/x/crypto/bcrypt"
)
func uploadHandler(c *gin.Context) {
err := c.Request.ParseMultipartForm(0) // unlimited
if err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
src, header, err := c.Request.FormFile("file")
if err != nil {
c.JSON(400, gin.H{"error": "No file uploaded"})
return
}
defer src.Close()
id := uuid.New().String()
delID := uuid.New().String()
cleanName := filepath.Base(header.Filename)
folderPath := filepath.Join("uploads", id)
os.MkdirAll(folderPath, 0755)
storagePath := filepath.Join(folderPath, cleanName)
dst, err := os.Create(storagePath)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
defer dst.Close()
written, err := io.Copy(dst, src)
fmt.Println("UPLOAD COMPLETE:", cleanName, written, "bytes")
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
expiry := time.Now().Add(24 * time.Hour)
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,
"download_url": fmt.Sprintf("/f/%s", id),
"delete_url": fmt.Sprintf("/api/file/delete/%s", delID),
})
}
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)
c.Header("Content-Disposition", fmt.Sprintf(`inline; filename="%s"`, record.Filename))
c.File(record.Path)
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"})
}
func loginHandler(c *gin.Context) {
username := c.PostForm("username")
password := c.PostForm("password")
var user User
if err := db.Where("username = ?", username).First(&user).Error; err != nil {
c.HTML(401, "login.html", gin.H{"Error": true})
return
}
if bcrypt.CompareHashAndPassword(
[]byte(user.Password),
[]byte(password),
) != nil {
c.HTML(401, "login.html", gin.H{"Error": true})
return
}
token, _ := generateToken(username)
c.SetCookie(
"auth",
token,
86400,
"/",
"",
false,
true,
)
c.Redirect(302, "/admin")
}