refactor(errors): handle api / app errors better
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
fd8b6bcdc1
commit
8c4c1022c3
10
api/api.go
10
api/api.go
@ -114,8 +114,8 @@ func (api *API) registerWebAppRoutes() {
|
|||||||
api.Router.GET("/progress", api.authWebAppMiddleware, api.appGetProgress)
|
api.Router.GET("/progress", api.authWebAppMiddleware, api.appGetProgress)
|
||||||
api.Router.GET("/documents", api.authWebAppMiddleware, api.appGetDocuments)
|
api.Router.GET("/documents", api.authWebAppMiddleware, api.appGetDocuments)
|
||||||
api.Router.GET("/documents/:document", api.authWebAppMiddleware, api.appGetDocument)
|
api.Router.GET("/documents/:document", api.authWebAppMiddleware, api.appGetDocument)
|
||||||
api.Router.GET("/documents/:document/cover", api.authWebAppMiddleware, api.getDocumentCover)
|
api.Router.GET("/documents/:document/cover", api.authWebAppMiddleware, api.createGetCoverHandler(appErrorPage))
|
||||||
api.Router.GET("/documents/:document/file", api.authWebAppMiddleware, api.downloadDocument)
|
api.Router.GET("/documents/:document/file", api.authWebAppMiddleware, api.createDownloadDocumentHandler(appErrorPage))
|
||||||
api.Router.GET("/login", api.appGetLogin)
|
api.Router.GET("/login", api.appGetLogin)
|
||||||
api.Router.GET("/logout", api.authWebAppMiddleware, api.appAuthLogout)
|
api.Router.GET("/logout", api.authWebAppMiddleware, api.appAuthLogout)
|
||||||
api.Router.GET("/register", api.appGetRegister)
|
api.Router.GET("/register", api.appGetRegister)
|
||||||
@ -153,7 +153,7 @@ func (api *API) registerKOAPIRoutes(apiGroup *gin.RouterGroup) {
|
|||||||
koGroup := apiGroup.Group("/ko")
|
koGroup := apiGroup.Group("/ko")
|
||||||
|
|
||||||
// KO Sync Routes (WebApp Uses - Progress & Activity)
|
// KO Sync Routes (WebApp Uses - Progress & Activity)
|
||||||
koGroup.GET("/documents/:document/file", api.authKOMiddleware, api.downloadDocument)
|
koGroup.GET("/documents/:document/file", api.authKOMiddleware, api.createDownloadDocumentHandler(apiErrorPage))
|
||||||
koGroup.GET("/syncs/progress/:document", api.authKOMiddleware, api.koGetProgress)
|
koGroup.GET("/syncs/progress/:document", api.authKOMiddleware, api.koGetProgress)
|
||||||
koGroup.GET("/users/auth", api.authKOMiddleware, api.koAuthorizeUser)
|
koGroup.GET("/users/auth", api.authKOMiddleware, api.koAuthorizeUser)
|
||||||
koGroup.POST("/activity", api.authKOMiddleware, api.koAddActivities)
|
koGroup.POST("/activity", api.authKOMiddleware, api.koAddActivities)
|
||||||
@ -181,8 +181,8 @@ func (api *API) registerOPDSRoutes(apiGroup *gin.RouterGroup) {
|
|||||||
opdsGroup.GET("/", api.authOPDSMiddleware, api.opdsEntry)
|
opdsGroup.GET("/", api.authOPDSMiddleware, api.opdsEntry)
|
||||||
opdsGroup.GET("/search.xml", api.authOPDSMiddleware, api.opdsSearchDescription)
|
opdsGroup.GET("/search.xml", api.authOPDSMiddleware, api.opdsSearchDescription)
|
||||||
opdsGroup.GET("/documents", api.authOPDSMiddleware, api.opdsDocuments)
|
opdsGroup.GET("/documents", api.authOPDSMiddleware, api.opdsDocuments)
|
||||||
opdsGroup.GET("/documents/:document/cover", api.authOPDSMiddleware, api.getDocumentCover)
|
opdsGroup.GET("/documents/:document/cover", api.authOPDSMiddleware, api.createGetCoverHandler(apiErrorPage))
|
||||||
opdsGroup.GET("/documents/:document/file", api.authOPDSMiddleware, api.downloadDocument)
|
opdsGroup.GET("/documents/:document/file", api.authOPDSMiddleware, api.createDownloadDocumentHandler(apiErrorPage))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) generateTemplates() *multitemplate.Renderer {
|
func (api *API) generateTemplates() *multitemplate.Renderer {
|
||||||
|
@ -13,7 +13,6 @@ import (
|
|||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
@ -154,14 +153,14 @@ func (api *API) appGetDocuments(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetDocumentsWithStats DB Error: ", err)
|
log.Error("GetDocumentsWithStats DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDocumentsWithStats DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDocumentsWithStats DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
length, err := api.DB.Queries.GetDocumentsSize(api.DB.Ctx, query)
|
length, err := api.DB.Queries.GetDocumentsSize(api.DB.Ctx, query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetDocumentsSize DB Error: ", err)
|
log.Error("GetDocumentsSize DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDocumentsSize DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDocumentsSize DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +192,7 @@ func (api *API) appGetDocument(c *gin.Context) {
|
|||||||
var rDocID requestDocumentID
|
var rDocID requestDocumentID
|
||||||
if err := c.ShouldBindUri(&rDocID); err != nil {
|
if err := c.ShouldBindUri(&rDocID); err != nil {
|
||||||
log.Error("Invalid URI Bind")
|
log.Error("Invalid URI Bind")
|
||||||
errorPage(c, http.StatusNotFound, "Invalid document.")
|
appErrorPage(c, http.StatusNotFound, "Invalid document.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,7 +202,7 @@ func (api *API) appGetDocument(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetDocumentWithStats DB Error: ", err)
|
log.Error("GetDocumentWithStats DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDocumentsWithStats DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDocumentsWithStats DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +231,7 @@ func (api *API) appGetProgress(c *gin.Context) {
|
|||||||
progress, err := api.DB.Queries.GetProgress(api.DB.Ctx, progressFilter)
|
progress, err := api.DB.Queries.GetProgress(api.DB.Ctx, progressFilter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetProgress DB Error: ", err)
|
log.Error("GetProgress DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetActivity DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetActivity DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,7 +258,7 @@ func (api *API) appGetActivity(c *gin.Context) {
|
|||||||
activity, err := api.DB.Queries.GetActivity(api.DB.Ctx, activityFilter)
|
activity, err := api.DB.Queries.GetActivity(api.DB.Ctx, activityFilter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetActivity DB Error: ", err)
|
log.Error("GetActivity DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetActivity DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetActivity DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,7 +274,7 @@ func (api *API) appGetHome(c *gin.Context) {
|
|||||||
graphData, err := api.DB.Queries.GetDailyReadStats(api.DB.Ctx, auth.UserName)
|
graphData, err := api.DB.Queries.GetDailyReadStats(api.DB.Ctx, auth.UserName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetDailyReadStats DB Error: ", err)
|
log.Error("GetDailyReadStats DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDailyReadStats DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDailyReadStats DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debug("GetDailyReadStats DB Performance: ", time.Since(start))
|
log.Debug("GetDailyReadStats DB Performance: ", time.Since(start))
|
||||||
@ -284,7 +283,7 @@ func (api *API) appGetHome(c *gin.Context) {
|
|||||||
databaseInfo, err := api.DB.Queries.GetDatabaseInfo(api.DB.Ctx, auth.UserName)
|
databaseInfo, err := api.DB.Queries.GetDatabaseInfo(api.DB.Ctx, auth.UserName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetDatabaseInfo DB Error: ", err)
|
log.Error("GetDatabaseInfo DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDatabaseInfo DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDatabaseInfo DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debug("GetDatabaseInfo DB Performance: ", time.Since(start))
|
log.Debug("GetDatabaseInfo DB Performance: ", time.Since(start))
|
||||||
@ -293,7 +292,7 @@ func (api *API) appGetHome(c *gin.Context) {
|
|||||||
streaks, err := api.DB.Queries.GetUserStreaks(api.DB.Ctx, auth.UserName)
|
streaks, err := api.DB.Queries.GetUserStreaks(api.DB.Ctx, auth.UserName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetUserStreaks DB Error: ", err)
|
log.Error("GetUserStreaks DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetUserStreaks DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetUserStreaks DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debug("GetUserStreaks DB Performance: ", time.Since(start))
|
log.Debug("GetUserStreaks DB Performance: ", time.Since(start))
|
||||||
@ -302,7 +301,7 @@ func (api *API) appGetHome(c *gin.Context) {
|
|||||||
userStatistics, err := api.DB.Queries.GetUserStatistics(api.DB.Ctx)
|
userStatistics, err := api.DB.Queries.GetUserStatistics(api.DB.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetUserStatistics DB Error: ", err)
|
log.Error("GetUserStatistics DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetUserStatistics DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetUserStatistics DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debug("GetUserStatistics DB Performance: ", time.Since(start))
|
log.Debug("GetUserStatistics DB Performance: ", time.Since(start))
|
||||||
@ -323,14 +322,14 @@ func (api *API) appGetSettings(c *gin.Context) {
|
|||||||
user, err := api.DB.Queries.GetUser(api.DB.Ctx, auth.UserName)
|
user, err := api.DB.Queries.GetUser(api.DB.Ctx, auth.UserName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetUser DB Error: ", err)
|
log.Error("GetUser DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetUser DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetUser DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
devices, err := api.DB.Queries.GetDevices(api.DB.Ctx, auth.UserName)
|
devices, err := api.DB.Queries.GetDevices(api.DB.Ctx, auth.UserName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetDevices DB Error: ", err)
|
log.Error("GetDevices DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDevices DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDevices DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,10 +350,10 @@ func (api *API) appGetAdminLogs(c *gin.Context) {
|
|||||||
templateVars, _ := api.getBaseTemplateVars("admin-logs", c)
|
templateVars, _ := api.getBaseTemplateVars("admin-logs", c)
|
||||||
|
|
||||||
// Open Log File
|
// Open Log File
|
||||||
logPath := path.Join(api.Config.ConfigPath, "logs/antholume.log")
|
logPath := filepath.Join(api.Config.ConfigPath, "logs/antholume.log")
|
||||||
logFile, err := os.Open(logPath)
|
logFile, err := os.Open(logPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorPage(c, http.StatusBadRequest, "Missing AnthoLume log file.")
|
appErrorPage(c, http.StatusBadRequest, "Missing AnthoLume log file.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer logFile.Close()
|
defer logFile.Close()
|
||||||
@ -392,7 +391,7 @@ func (api *API) appGetAdminUsers(c *gin.Context) {
|
|||||||
users, err := api.DB.Queries.GetUsers(api.DB.Ctx)
|
users, err := api.DB.Queries.GetUsers(api.DB.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetUsers DB Error: ", err)
|
log.Error("GetUsers DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetUsers DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetUsers DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,7 +410,7 @@ func (api *API) appPerformAdminAction(c *gin.Context) {
|
|||||||
var rAdminAction requestAdminAction
|
var rAdminAction requestAdminAction
|
||||||
if err := c.ShouldBind(&rAdminAction); err != nil {
|
if err := c.ShouldBind(&rAdminAction); err != nil {
|
||||||
log.Error("Invalid Form Bind: ", err)
|
log.Error("Invalid Form Bind: ", err)
|
||||||
errorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
|
appErrorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,7 +464,7 @@ func (api *API) appGetSearch(c *gin.Context) {
|
|||||||
// Search
|
// Search
|
||||||
searchResults, err := search.SearchBook(*sParams.Query, *sParams.Source)
|
searchResults, err := search.SearchBook(*sParams.Query, *sParams.Source)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("Search Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("Search Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,7 +504,7 @@ func (api *API) appGetDocumentProgress(c *gin.Context) {
|
|||||||
var rDoc requestDocumentID
|
var rDoc requestDocumentID
|
||||||
if err := c.ShouldBindUri(&rDoc); err != nil {
|
if err := c.ShouldBindUri(&rDoc); err != nil {
|
||||||
log.Error("Invalid URI Bind")
|
log.Error("Invalid URI Bind")
|
||||||
errorPage(c, http.StatusNotFound, "Invalid document.")
|
appErrorPage(c, http.StatusNotFound, "Invalid document.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,7 +515,7 @@ func (api *API) appGetDocumentProgress(c *gin.Context) {
|
|||||||
|
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
log.Error("UpsertDocument DB Error: ", err)
|
log.Error("UpsertDocument DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("UpsertDocument DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("UpsertDocument DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,7 +525,7 @@ func (api *API) appGetDocumentProgress(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetDocumentWithStats DB Error: ", err)
|
log.Error("GetDocumentWithStats DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDocumentWithStats DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDocumentWithStats DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -550,7 +549,7 @@ func (api *API) appGetDevices(c *gin.Context) {
|
|||||||
|
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
log.Error("GetDevices DB Error: ", err)
|
log.Error("GetDevices DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDevices DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDevices DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -561,7 +560,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
|
|||||||
var rDocUpload requestDocumentUpload
|
var rDocUpload requestDocumentUpload
|
||||||
if err := c.ShouldBind(&rDocUpload); err != nil {
|
if err := c.ShouldBind(&rDocUpload); err != nil {
|
||||||
log.Error("Invalid Form Bind")
|
log.Error("Invalid Form Bind")
|
||||||
errorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
|
appErrorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -574,14 +573,14 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
|
|||||||
uploadedFile, err := rDocUpload.DocumentFile.Open()
|
uploadedFile, err := rDocUpload.DocumentFile.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("File Error: ", err)
|
log.Error("File Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to open file.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to open file.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fileMime, err := mimetype.DetectReader(uploadedFile)
|
fileMime, err := mimetype.DetectReader(uploadedFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("MIME Error")
|
log.Error("MIME Error")
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to detect filetype.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to detect filetype.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fileExtension := fileMime.Extension()
|
fileExtension := fileMime.Extension()
|
||||||
@ -589,7 +588,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
|
|||||||
// Validate Extension
|
// Validate Extension
|
||||||
if !slices.Contains([]string{".epub"}, fileExtension) {
|
if !slices.Contains([]string{".epub"}, fileExtension) {
|
||||||
log.Error("Invalid FileType: ", fileExtension)
|
log.Error("Invalid FileType: ", fileExtension)
|
||||||
errorPage(c, http.StatusBadRequest, "Invalid filetype.")
|
appErrorPage(c, http.StatusBadRequest, "Invalid filetype.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -597,7 +596,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
|
|||||||
tempFile, err := os.CreateTemp("", "book")
|
tempFile, err := os.CreateTemp("", "book")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("Temp File Create Error: ", err)
|
log.Warn("Temp File Create Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to create temp file.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to create temp file.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer os.Remove(tempFile.Name())
|
defer os.Remove(tempFile.Name())
|
||||||
@ -607,7 +606,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
|
|||||||
err = c.SaveUploadedFile(rDocUpload.DocumentFile, tempFile.Name())
|
err = c.SaveUploadedFile(rDocUpload.DocumentFile, tempFile.Name())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("File Error: ", err)
|
log.Error("File Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to save file.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to save file.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -615,7 +614,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
|
|||||||
metadataInfo, err := metadata.GetMetadata(tempFile.Name())
|
metadataInfo, err := metadata.GetMetadata(tempFile.Name())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("GetMetadata Error: ", err)
|
log.Warn("GetMetadata Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to acquire file metadata.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to acquire file metadata.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -623,7 +622,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
|
|||||||
partialMD5, err := utils.CalculatePartialMD5(tempFile.Name())
|
partialMD5, err := utils.CalculatePartialMD5(tempFile.Name())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("Partial MD5 Error: ", err)
|
log.Warn("Partial MD5 Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to calculate partial MD5.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to calculate partial MD5.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -638,7 +637,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
|
|||||||
fileHash, err := getFileMD5(tempFile.Name())
|
fileHash, err := getFileMD5(tempFile.Name())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("MD5 Hash Failure: ", err)
|
log.Error("MD5 Hash Failure: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to calculate MD5.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to calculate MD5.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,7 +645,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
|
|||||||
wordCount, err := metadata.GetWordCount(tempFile.Name())
|
wordCount, err := metadata.GetWordCount(tempFile.Name())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Word Count Failure: ", err)
|
log.Error("Word Count Failure: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to calculate word count.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to calculate word count.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -675,7 +674,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
|
|||||||
destFile, err := os.Create(safePath)
|
destFile, err := os.Create(safePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Dest File Error: ", err)
|
log.Error("Dest File Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to save file.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to save file.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer destFile.Close()
|
defer destFile.Close()
|
||||||
@ -683,7 +682,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
|
|||||||
// Copy File
|
// Copy File
|
||||||
if _, err = io.Copy(destFile, tempFile); err != nil {
|
if _, err = io.Copy(destFile, tempFile); err != nil {
|
||||||
log.Error("Copy Temp File Error: ", err)
|
log.Error("Copy Temp File Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to save file.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to save file.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,7 +697,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
|
|||||||
Filepath: &fileName,
|
Filepath: &fileName,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.Error("UpsertDocument DB Error: ", err)
|
log.Error("UpsertDocument DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("UpsertDocument DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("UpsertDocument DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -709,14 +708,14 @@ func (api *API) appEditDocument(c *gin.Context) {
|
|||||||
var rDocID requestDocumentID
|
var rDocID requestDocumentID
|
||||||
if err := c.ShouldBindUri(&rDocID); err != nil {
|
if err := c.ShouldBindUri(&rDocID); err != nil {
|
||||||
log.Error("Invalid URI Bind")
|
log.Error("Invalid URI Bind")
|
||||||
errorPage(c, http.StatusNotFound, "Invalid document.")
|
appErrorPage(c, http.StatusNotFound, "Invalid document.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var rDocEdit requestDocumentEdit
|
var rDocEdit requestDocumentEdit
|
||||||
if err := c.ShouldBind(&rDocEdit); err != nil {
|
if err := c.ShouldBind(&rDocEdit); err != nil {
|
||||||
log.Error("Invalid Form Bind")
|
log.Error("Invalid Form Bind")
|
||||||
errorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
|
appErrorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -730,7 +729,7 @@ func (api *API) appEditDocument(c *gin.Context) {
|
|||||||
rDocEdit.CoverGBID == nil &&
|
rDocEdit.CoverGBID == nil &&
|
||||||
rDocEdit.CoverFile == nil {
|
rDocEdit.CoverFile == nil {
|
||||||
log.Error("Missing Form Values")
|
log.Error("Missing Form Values")
|
||||||
errorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
|
appErrorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -744,14 +743,14 @@ func (api *API) appEditDocument(c *gin.Context) {
|
|||||||
uploadedFile, err := rDocEdit.CoverFile.Open()
|
uploadedFile, err := rDocEdit.CoverFile.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("File Error")
|
log.Error("File Error")
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to open file.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to open file.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fileMime, err := mimetype.DetectReader(uploadedFile)
|
fileMime, err := mimetype.DetectReader(uploadedFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("MIME Error")
|
log.Error("MIME Error")
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to detect filetype.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to detect filetype.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fileExtension := fileMime.Extension()
|
fileExtension := fileMime.Extension()
|
||||||
@ -759,7 +758,7 @@ func (api *API) appEditDocument(c *gin.Context) {
|
|||||||
// Validate Extension
|
// Validate Extension
|
||||||
if !slices.Contains([]string{".jpg", ".png"}, fileExtension) {
|
if !slices.Contains([]string{".jpg", ".png"}, fileExtension) {
|
||||||
log.Error("Invalid FileType: ", fileExtension)
|
log.Error("Invalid FileType: ", fileExtension)
|
||||||
errorPage(c, http.StatusBadRequest, "Invalid filetype.")
|
appErrorPage(c, http.StatusBadRequest, "Invalid filetype.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -771,7 +770,7 @@ func (api *API) appEditDocument(c *gin.Context) {
|
|||||||
err = c.SaveUploadedFile(rDocEdit.CoverFile, safePath)
|
err = c.SaveUploadedFile(rDocEdit.CoverFile, safePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("File Error: ", err)
|
log.Error("File Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to save file.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to save file.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -795,7 +794,7 @@ func (api *API) appEditDocument(c *gin.Context) {
|
|||||||
Coverfile: coverFileName,
|
Coverfile: coverFileName,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.Error("UpsertDocument DB Error: ", err)
|
log.Error("UpsertDocument DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("UpsertDocument DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("UpsertDocument DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -807,18 +806,18 @@ func (api *API) appDeleteDocument(c *gin.Context) {
|
|||||||
var rDocID requestDocumentID
|
var rDocID requestDocumentID
|
||||||
if err := c.ShouldBindUri(&rDocID); err != nil {
|
if err := c.ShouldBindUri(&rDocID); err != nil {
|
||||||
log.Error("Invalid URI Bind")
|
log.Error("Invalid URI Bind")
|
||||||
errorPage(c, http.StatusNotFound, "Invalid document.")
|
appErrorPage(c, http.StatusNotFound, "Invalid document.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
changed, err := api.DB.Queries.DeleteDocument(api.DB.Ctx, rDocID.DocumentID)
|
changed, err := api.DB.Queries.DeleteDocument(api.DB.Ctx, rDocID.DocumentID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("DeleteDocument DB Error")
|
log.Error("DeleteDocument DB Error")
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("DeleteDocument DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("DeleteDocument DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if changed == 0 {
|
if changed == 0 {
|
||||||
log.Error("DeleteDocument DB Error")
|
log.Error("DeleteDocument DB Error")
|
||||||
errorPage(c, http.StatusNotFound, "Invalid document.")
|
appErrorPage(c, http.StatusNotFound, "Invalid document.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -829,14 +828,14 @@ func (api *API) appIdentifyDocument(c *gin.Context) {
|
|||||||
var rDocID requestDocumentID
|
var rDocID requestDocumentID
|
||||||
if err := c.ShouldBindUri(&rDocID); err != nil {
|
if err := c.ShouldBindUri(&rDocID); err != nil {
|
||||||
log.Error("Invalid URI Bind")
|
log.Error("Invalid URI Bind")
|
||||||
errorPage(c, http.StatusNotFound, "Invalid document.")
|
appErrorPage(c, http.StatusNotFound, "Invalid document.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var rDocIdentify requestDocumentIdentify
|
var rDocIdentify requestDocumentIdentify
|
||||||
if err := c.ShouldBind(&rDocIdentify); err != nil {
|
if err := c.ShouldBind(&rDocIdentify); err != nil {
|
||||||
log.Error("Invalid Form Bind")
|
log.Error("Invalid Form Bind")
|
||||||
errorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
|
appErrorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -854,7 +853,7 @@ func (api *API) appIdentifyDocument(c *gin.Context) {
|
|||||||
// Validate Values
|
// Validate Values
|
||||||
if rDocIdentify.ISBN == nil && rDocIdentify.Title == nil && rDocIdentify.Author == nil {
|
if rDocIdentify.ISBN == nil && rDocIdentify.Title == nil && rDocIdentify.Author == nil {
|
||||||
log.Error("Invalid Form")
|
log.Error("Invalid Form")
|
||||||
errorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
|
appErrorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -897,7 +896,7 @@ func (api *API) appIdentifyDocument(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetDocumentWithStats DB Error: ", err)
|
log.Error("GetDocumentWithStats DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDocumentWithStats DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDocumentWithStats DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -911,7 +910,7 @@ func (api *API) appSaveNewDocument(c *gin.Context) {
|
|||||||
var rDocAdd requestDocumentAdd
|
var rDocAdd requestDocumentAdd
|
||||||
if err := c.ShouldBind(&rDocAdd); err != nil {
|
if err := c.ShouldBind(&rDocAdd); err != nil {
|
||||||
log.Error("Invalid Form Bind")
|
log.Error("Invalid Form Bind")
|
||||||
errorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
|
appErrorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1069,14 +1068,14 @@ func (api *API) appEditSettings(c *gin.Context) {
|
|||||||
var rUserSettings requestSettingsEdit
|
var rUserSettings requestSettingsEdit
|
||||||
if err := c.ShouldBind(&rUserSettings); err != nil {
|
if err := c.ShouldBind(&rUserSettings); err != nil {
|
||||||
log.Error("Invalid Form Bind")
|
log.Error("Invalid Form Bind")
|
||||||
errorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
|
appErrorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate Something Exists
|
// Validate Something Exists
|
||||||
if rUserSettings.Password == nil && rUserSettings.NewPassword == nil && rUserSettings.TimeOffset == nil {
|
if rUserSettings.Password == nil && rUserSettings.NewPassword == nil && rUserSettings.TimeOffset == nil {
|
||||||
log.Error("Missing Form Values")
|
log.Error("Missing Form Values")
|
||||||
errorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
|
appErrorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1114,7 +1113,7 @@ func (api *API) appEditSettings(c *gin.Context) {
|
|||||||
_, err := api.DB.Queries.UpdateUser(api.DB.Ctx, newUserSettings)
|
_, err := api.DB.Queries.UpdateUser(api.DB.Ctx, newUserSettings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("UpdateUser DB Error: ", err)
|
log.Error("UpdateUser DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("UpdateUser DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("UpdateUser DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1122,7 +1121,7 @@ func (api *API) appEditSettings(c *gin.Context) {
|
|||||||
user, err := api.DB.Queries.GetUser(api.DB.Ctx, auth.UserName)
|
user, err := api.DB.Queries.GetUser(api.DB.Ctx, auth.UserName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetUser DB Error: ", err)
|
log.Error("GetUser DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetUser DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetUser DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1130,7 +1129,7 @@ func (api *API) appEditSettings(c *gin.Context) {
|
|||||||
devices, err := api.DB.Queries.GetDevices(api.DB.Ctx, auth.UserName)
|
devices, err := api.DB.Queries.GetDevices(api.DB.Ctx, auth.UserName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetDevices DB Error: ", err)
|
log.Error("GetDevices DB Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDevices DB Error: %v", err))
|
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDevices DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1143,7 +1142,7 @@ func (api *API) appEditSettings(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) appDemoModeError(c *gin.Context) {
|
func (api *API) appDemoModeError(c *gin.Context) {
|
||||||
errorPage(c, http.StatusUnauthorized, "Not Allowed in Demo Mode")
|
appErrorPage(c, http.StatusUnauthorized, "Not Allowed in Demo Mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) getDocumentsWordCount(documents []database.GetDocumentsWithStatsRow) error {
|
func (api *API) getDocumentsWordCount(documents []database.GetDocumentsWithStatsRow) error {
|
||||||
@ -1221,7 +1220,7 @@ func bindQueryParams(c *gin.Context, defaultLimit int64) queryParams {
|
|||||||
return qParams
|
return qParams
|
||||||
}
|
}
|
||||||
|
|
||||||
func errorPage(c *gin.Context, errorCode int, errorMessage string) {
|
func appErrorPage(c *gin.Context, errorCode int, errorMessage string) {
|
||||||
var errorHuman string = "We're not even sure what happened."
|
var errorHuman string = "We're not even sure what happened."
|
||||||
|
|
||||||
switch errorCode {
|
switch errorCode {
|
||||||
@ -1324,14 +1323,14 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
|
|||||||
uploadedFile, err := rAdminAction.RestoreFile.Open()
|
uploadedFile, err := rAdminAction.RestoreFile.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("File Error: ", err)
|
log.Error("File Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to open file.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to open file.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fileMime, err := mimetype.DetectReader(uploadedFile)
|
fileMime, err := mimetype.DetectReader(uploadedFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("MIME Error")
|
log.Error("MIME Error")
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to detect filetype.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to detect filetype.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fileExtension := fileMime.Extension()
|
fileExtension := fileMime.Extension()
|
||||||
@ -1339,7 +1338,7 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
|
|||||||
// Validate Extension
|
// Validate Extension
|
||||||
if !slices.Contains([]string{".zip"}, fileExtension) {
|
if !slices.Contains([]string{".zip"}, fileExtension) {
|
||||||
log.Error("Invalid FileType: ", fileExtension)
|
log.Error("Invalid FileType: ", fileExtension)
|
||||||
errorPage(c, http.StatusBadRequest, "Invalid filetype.")
|
appErrorPage(c, http.StatusBadRequest, "Invalid filetype.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1347,7 +1346,7 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
|
|||||||
tempFile, err := os.CreateTemp("", "restore")
|
tempFile, err := os.CreateTemp("", "restore")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("Temp File Create Error: ", err)
|
log.Warn("Temp File Create Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to create temp file.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to create temp file.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer os.Remove(tempFile.Name())
|
defer os.Remove(tempFile.Name())
|
||||||
@ -1357,7 +1356,7 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
|
|||||||
err = c.SaveUploadedFile(rAdminAction.RestoreFile, tempFile.Name())
|
err = c.SaveUploadedFile(rAdminAction.RestoreFile, tempFile.Name())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("File Error: ", err)
|
log.Error("File Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to save file.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to save file.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1365,23 +1364,23 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
|
|||||||
fileInfo, err := tempFile.Stat()
|
fileInfo, err := tempFile.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("File Error: ", err)
|
log.Error("File Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to read file.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to read file.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create ZIP Reader
|
// Create ZIP Reader
|
||||||
r, err := zip.NewReader(tempFile, fileInfo.Size())
|
zipReader, err := zip.NewReader(tempFile, fileInfo.Size())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("ZIP Error: ", err)
|
log.Error("ZIP Error: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to read zip.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to read zip.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate ZIP Contents
|
// Validate ZIP Contents
|
||||||
hasDBFile := false
|
hasDBFile := false
|
||||||
hasUnknownFile := false
|
hasUnknownFile := false
|
||||||
for _, f := range r.File {
|
for _, file := range zipReader.File {
|
||||||
fileName := strings.TrimPrefix(f.Name, "/")
|
fileName := strings.TrimPrefix(file.Name, "/")
|
||||||
if fileName == "antholume.db" {
|
if fileName == "antholume.db" {
|
||||||
hasDBFile = true
|
hasDBFile = true
|
||||||
break
|
break
|
||||||
@ -1394,20 +1393,20 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
|
|||||||
// Invalid ZIP
|
// Invalid ZIP
|
||||||
if !hasDBFile {
|
if !hasDBFile {
|
||||||
log.Error("Invalid ZIP File - Missing DB")
|
log.Error("Invalid ZIP File - Missing DB")
|
||||||
errorPage(c, http.StatusInternalServerError, "Invalid Restore ZIP - Missing DB")
|
appErrorPage(c, http.StatusInternalServerError, "Invalid Restore ZIP - Missing DB")
|
||||||
return
|
return
|
||||||
} else if hasUnknownFile {
|
} else if hasUnknownFile {
|
||||||
log.Error("Invalid ZIP File - Invalid File(s)")
|
log.Error("Invalid ZIP File - Invalid File(s)")
|
||||||
errorPage(c, http.StatusInternalServerError, "Invalid Restore ZIP - Invalid File(s)")
|
appErrorPage(c, http.StatusInternalServerError, "Invalid Restore ZIP - Invalid File(s)")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create Backup File
|
// Create Backup File
|
||||||
backupFilePath := path.Join(api.Config.ConfigPath, fmt.Sprintf("backup/AnthoLumeBackup_%s.zip", time.Now().Format("20060102")))
|
backupFilePath := filepath.Join(api.Config.ConfigPath, fmt.Sprintf("backup/AnthoLumeBackup_%s.zip", time.Now().Format("20060102")))
|
||||||
backupFile, err := os.Create(backupFilePath)
|
backupFile, err := os.Create(backupFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Unable to create backup file: ", err)
|
log.Error("Unable to create backup file: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to create backup file.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to create backup file.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer backupFile.Close()
|
defer backupFile.Close()
|
||||||
@ -1417,7 +1416,26 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
|
|||||||
err = api.createBackup(w, []string{"covers", "documents"})
|
err = api.createBackup(w, []string{"covers", "documents"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Unable to save backup file: ", err)
|
log.Error("Unable to save backup file: ", err)
|
||||||
errorPage(c, http.StatusInternalServerError, "Unable to save backup file.")
|
appErrorPage(c, http.StatusInternalServerError, "Unable to save backup file.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove Data
|
||||||
|
err = api.removeData()
|
||||||
|
if err != nil {
|
||||||
|
appErrorPage(c, http.StatusInternalServerError, "Unable to delete data.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore Data
|
||||||
|
err = api.restoreData(zipReader)
|
||||||
|
if err != nil {
|
||||||
|
appErrorPage(c, http.StatusInternalServerError, "Unable to restore data.")
|
||||||
|
|
||||||
|
// Panic?
|
||||||
|
|
||||||
|
log.Panic("Oh no")
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1425,6 +1443,56 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
|
|||||||
// - Extract from temp directory
|
// - Extract from temp directory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api *API) restoreData(zipReader *zip.Reader) error {
|
||||||
|
for _, file := range zipReader.File {
|
||||||
|
rc, err := file.Open()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer rc.Close()
|
||||||
|
|
||||||
|
destPath := filepath.Join(api.Config.DataPath, file.Name)
|
||||||
|
destFile, err := os.Create(destPath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error creating destination file:", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer destFile.Close()
|
||||||
|
|
||||||
|
// Copy the contents from the zip file to the destination file.
|
||||||
|
if _, err := io.Copy(destFile, rc); err != nil {
|
||||||
|
fmt.Println("Error copying file contents:", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Extracted: %s\n", destPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *API) removeData() error {
|
||||||
|
allPaths := []string{
|
||||||
|
"covers",
|
||||||
|
"documents",
|
||||||
|
"antholume.db",
|
||||||
|
"antholume.db-wal",
|
||||||
|
"antholume.db-shm",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, name := range allPaths {
|
||||||
|
fullPath := filepath.Join(api.Config.DataPath, name)
|
||||||
|
err := os.RemoveAll(fullPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Unable to delete %s: %v", name, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (api *API) createBackup(w io.Writer, directories []string) error {
|
func (api *API) createBackup(w io.Writer, directories []string) error {
|
||||||
ar := zip.NewWriter(w)
|
ar := zip.NewWriter(w)
|
||||||
|
|
||||||
@ -1448,7 +1516,7 @@ func (api *API) createBackup(w io.Writer, directories []string) error {
|
|||||||
folderName := filepath.Base(filepath.Dir(currentPath))
|
folderName := filepath.Base(filepath.Dir(currentPath))
|
||||||
|
|
||||||
// Create File in Export
|
// Create File in Export
|
||||||
newF, err := ar.Create(path.Join(folderName, fileName))
|
newF, err := ar.Create(filepath.Join(folderName, fileName))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1464,7 +1532,7 @@ func (api *API) createBackup(w io.Writer, directories []string) error {
|
|||||||
|
|
||||||
// Get DB Path
|
// Get DB Path
|
||||||
fileName := fmt.Sprintf("%s.db", api.Config.DBName)
|
fileName := fmt.Sprintf("%s.db", api.Config.DBName)
|
||||||
dbLocation := path.Join(api.Config.ConfigPath, fileName)
|
dbLocation := filepath.Join(api.Config.ConfigPath, fileName)
|
||||||
|
|
||||||
// Copy Database File
|
// Copy Database File
|
||||||
dbFile, err := os.Open(dbLocation)
|
dbFile, err := os.Open(dbLocation)
|
||||||
@ -1481,7 +1549,7 @@ func (api *API) createBackup(w io.Writer, directories []string) error {
|
|||||||
|
|
||||||
// Backup Covers & Documents
|
// Backup Covers & Documents
|
||||||
for _, dir := range directories {
|
for _, dir := range directories {
|
||||||
err = filepath.WalkDir(path.Join(api.Config.DataPath, dir), exportWalker)
|
err = filepath.WalkDir(filepath.Join(api.Config.DataPath, dir), exportWalker)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ func (api *API) authAdminWebAppMiddleware(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
errorPage(c, http.StatusUnauthorized, "Admin Permissions Required")
|
appErrorPage(c, http.StatusUnauthorized, "Admin Permissions Required")
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -175,7 +175,7 @@ func (api *API) appAuthFormLogin(c *gin.Context) {
|
|||||||
|
|
||||||
func (api *API) appAuthFormRegister(c *gin.Context) {
|
func (api *API) appAuthFormRegister(c *gin.Context) {
|
||||||
if !api.Config.RegistrationEnabled {
|
if !api.Config.RegistrationEnabled {
|
||||||
errorPage(c, http.StatusUnauthorized, "Nice try. Registration is disabled.")
|
appErrorPage(c, http.StatusUnauthorized, "Nice try. Registration is disabled.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +236,7 @@ func (api *API) appAuthFormRegister(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
session := sessions.Default(c)
|
session := sessions.Default(c)
|
||||||
if err := setSession(session, auth); err != nil {
|
if err := setSession(session, auth); err != nil {
|
||||||
errorPage(c, http.StatusUnauthorized, "Unauthorized.")
|
appErrorPage(c, http.StatusUnauthorized, "Unauthorized.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,11 +11,12 @@ import (
|
|||||||
"reichard.io/antholume/metadata"
|
"reichard.io/antholume/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (api *API) downloadDocument(c *gin.Context) {
|
func (api *API) createDownloadDocumentHandler(errorFunc func(*gin.Context, int, string)) func(*gin.Context) {
|
||||||
|
return func(c *gin.Context) {
|
||||||
var rDoc requestDocumentID
|
var rDoc requestDocumentID
|
||||||
if err := c.ShouldBindUri(&rDoc); err != nil {
|
if err := c.ShouldBindUri(&rDoc); err != nil {
|
||||||
log.Error("Invalid URI Bind")
|
log.Error("Invalid URI Bind")
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
|
errorFunc(c, http.StatusBadRequest, "Invalid Request")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,13 +24,13 @@ func (api *API) downloadDocument(c *gin.Context) {
|
|||||||
document, err := api.DB.Queries.GetDocument(api.DB.Ctx, rDoc.DocumentID)
|
document, err := api.DB.Queries.GetDocument(api.DB.Ctx, rDoc.DocumentID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetDocument DB Error:", err)
|
log.Error("GetDocument DB Error:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Unknown Document"})
|
errorFunc(c, http.StatusBadRequest, "Unknown Document")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if document.Filepath == nil {
|
if document.Filepath == nil {
|
||||||
log.Error("Document Doesn't Have File:", rDoc.DocumentID)
|
log.Error("Document Doesn't Have File:", rDoc.DocumentID)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Document Doesn't Exist"})
|
errorFunc(c, http.StatusBadRequest, "Document Doesn't Exist")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,20 +41,22 @@ func (api *API) downloadDocument(c *gin.Context) {
|
|||||||
_, err = os.Stat(filePath)
|
_, err = os.Stat(filePath)
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
log.Error("File Doesn't Exist:", rDoc.DocumentID)
|
log.Error("File Doesn't Exist:", rDoc.DocumentID)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Document Doesn't Exists"})
|
errorFunc(c, http.StatusBadRequest, "Document Doesn't Exist")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force Download (Security)
|
// Force Download
|
||||||
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filepath.Base(*document.Filepath)))
|
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filepath.Base(*document.Filepath)))
|
||||||
c.File(filePath)
|
c.File(filePath)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) getDocumentCover(c *gin.Context) {
|
func (api *API) createGetCoverHandler(errorFunc func(*gin.Context, int, string)) func(*gin.Context) {
|
||||||
|
return func(c *gin.Context) {
|
||||||
var rDoc requestDocumentID
|
var rDoc requestDocumentID
|
||||||
if err := c.ShouldBindUri(&rDoc); err != nil {
|
if err := c.ShouldBindUri(&rDoc); err != nil {
|
||||||
log.Error("Invalid URI Bind")
|
log.Error("Invalid URI Bind")
|
||||||
errorPage(c, http.StatusNotFound, "Invalid cover.")
|
errorFunc(c, http.StatusNotFound, "Invalid cover.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +64,7 @@ func (api *API) getDocumentCover(c *gin.Context) {
|
|||||||
document, err := api.DB.Queries.GetDocument(api.DB.Ctx, rDoc.DocumentID)
|
document, err := api.DB.Queries.GetDocument(api.DB.Ctx, rDoc.DocumentID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetDocument DB Error:", err)
|
log.Error("GetDocument DB Error:", err)
|
||||||
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("GetDocument DB Error: %v", err))
|
errorFunc(c, http.StatusInternalServerError, fmt.Sprintf("GetDocument DB Error: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,4 +140,5 @@ func (api *API) getDocumentCover(c *gin.Context) {
|
|||||||
|
|
||||||
coverFilePath := filepath.Join(coverDir, coverFile)
|
coverFilePath := filepath.Join(coverDir, coverFile)
|
||||||
c.File(coverFilePath)
|
c.File(coverFilePath)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,20 +90,20 @@ func (api *API) koCreateUser(c *gin.Context) {
|
|||||||
var rUser requestUser
|
var rUser requestUser
|
||||||
if err := c.ShouldBindJSON(&rUser); err != nil {
|
if err := c.ShouldBindJSON(&rUser); err != nil {
|
||||||
log.Error("Invalid JSON Bind")
|
log.Error("Invalid JSON Bind")
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid User Data"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid User Data")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if rUser.Username == "" || rUser.Password == "" {
|
if rUser.Username == "" || rUser.Password == "" {
|
||||||
log.Error("Invalid User - Empty Username or Password")
|
log.Error("Invalid User - Empty Username or Password")
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid User Data"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid User Data")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
hashedPassword, err := argon2.CreateHash(rUser.Password, argon2.DefaultParams)
|
hashedPassword, err := argon2.CreateHash(rUser.Password, argon2.DefaultParams)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Argon2 Hash Failure:", err)
|
log.Error("Argon2 Hash Failure:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Unknown Error"})
|
apiErrorPage(c, http.StatusBadRequest, "Unknown Error")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,13 +113,14 @@ func (api *API) koCreateUser(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("CreateUser DB Error:", err)
|
log.Error("CreateUser DB Error:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid User Data"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid User Data")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// User Exists
|
// User Exists
|
||||||
if rows == 0 {
|
if rows == 0 {
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "User Already Exists"})
|
log.Error("User Already Exists:", rUser.Username)
|
||||||
|
apiErrorPage(c, http.StatusBadRequest, "User Already Exists")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +138,7 @@ func (api *API) koSetProgress(c *gin.Context) {
|
|||||||
var rPosition requestPosition
|
var rPosition requestPosition
|
||||||
if err := c.ShouldBindJSON(&rPosition); err != nil {
|
if err := c.ShouldBindJSON(&rPosition); err != nil {
|
||||||
log.Error("Invalid JSON Bind")
|
log.Error("Invalid JSON Bind")
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Progress Data"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid Progress Data")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,7 +169,7 @@ func (api *API) koSetProgress(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("UpdateProgress DB Error:", err)
|
log.Error("UpdateProgress DB Error:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid Request")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,7 +188,7 @@ func (api *API) koGetProgress(c *gin.Context) {
|
|||||||
var rDocID requestDocumentID
|
var rDocID requestDocumentID
|
||||||
if err := c.ShouldBindUri(&rDocID); err != nil {
|
if err := c.ShouldBindUri(&rDocID); err != nil {
|
||||||
log.Error("Invalid URI Bind")
|
log.Error("Invalid URI Bind")
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid Request")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +203,7 @@ func (api *API) koGetProgress(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
log.Error("GetDocumentProgress DB Error:", err)
|
log.Error("GetDocumentProgress DB Error:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Document"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid Document")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,7 +225,7 @@ func (api *API) koAddActivities(c *gin.Context) {
|
|||||||
var rActivity requestActivity
|
var rActivity requestActivity
|
||||||
if err := c.ShouldBindJSON(&rActivity); err != nil {
|
if err := c.ShouldBindJSON(&rActivity); err != nil {
|
||||||
log.Error("Invalid JSON Bind")
|
log.Error("Invalid JSON Bind")
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Activity"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid Activity")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +233,7 @@ func (api *API) koAddActivities(c *gin.Context) {
|
|||||||
tx, err := api.DB.DB.Begin()
|
tx, err := api.DB.DB.Begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Transaction Begin DB Error:", err)
|
log.Error("Transaction Begin DB Error:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Unknown Error"})
|
apiErrorPage(c, http.StatusBadRequest, "Unknown Error")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,7 +254,7 @@ func (api *API) koAddActivities(c *gin.Context) {
|
|||||||
ID: doc,
|
ID: doc,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.Error("UpsertDocument DB Error:", err)
|
log.Error("UpsertDocument DB Error:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Document"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid Document")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -266,7 +267,7 @@ func (api *API) koAddActivities(c *gin.Context) {
|
|||||||
LastSynced: time.Now().UTC().Format(time.RFC3339),
|
LastSynced: time.Now().UTC().Format(time.RFC3339),
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.Error("UpsertDevice DB Error:", err)
|
log.Error("UpsertDevice DB Error:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Device"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid Device")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,7 +283,7 @@ func (api *API) koAddActivities(c *gin.Context) {
|
|||||||
EndPercentage: float64(item.Page+1) / float64(item.Pages),
|
EndPercentage: float64(item.Page+1) / float64(item.Pages),
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.Error("AddActivity DB Error:", err)
|
log.Error("AddActivity DB Error:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Activity"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid Activity")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -290,7 +291,7 @@ func (api *API) koAddActivities(c *gin.Context) {
|
|||||||
// Commit Transaction
|
// Commit Transaction
|
||||||
if err := tx.Commit(); err != nil {
|
if err := tx.Commit(); err != nil {
|
||||||
log.Error("Transaction Commit DB Error:", err)
|
log.Error("Transaction Commit DB Error:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Unknown Error"})
|
apiErrorPage(c, http.StatusBadRequest, "Unknown Error")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,7 +309,7 @@ func (api *API) koCheckActivitySync(c *gin.Context) {
|
|||||||
var rCheckActivity requestCheckActivitySync
|
var rCheckActivity requestCheckActivitySync
|
||||||
if err := c.ShouldBindJSON(&rCheckActivity); err != nil {
|
if err := c.ShouldBindJSON(&rCheckActivity); err != nil {
|
||||||
log.Error("Invalid JSON Bind")
|
log.Error("Invalid JSON Bind")
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid Request")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,7 +321,7 @@ func (api *API) koCheckActivitySync(c *gin.Context) {
|
|||||||
LastSynced: time.Now().UTC().Format(time.RFC3339),
|
LastSynced: time.Now().UTC().Format(time.RFC3339),
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.Error("UpsertDevice DB Error", err)
|
log.Error("UpsertDevice DB Error", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Device"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid Device")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,7 +334,7 @@ func (api *API) koCheckActivitySync(c *gin.Context) {
|
|||||||
lastActivity = time.UnixMilli(0).Format(time.RFC3339)
|
lastActivity = time.UnixMilli(0).Format(time.RFC3339)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
log.Error("GetLastActivity DB Error:", err)
|
log.Error("GetLastActivity DB Error:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Unknown Error"})
|
apiErrorPage(c, http.StatusBadRequest, "Unknown Error")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,7 +342,7 @@ func (api *API) koCheckActivitySync(c *gin.Context) {
|
|||||||
parsedTime, err := time.Parse(time.RFC3339, lastActivity)
|
parsedTime, err := time.Parse(time.RFC3339, lastActivity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Time Parse Error:", err)
|
log.Error("Time Parse Error:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Unknown Error"})
|
apiErrorPage(c, http.StatusBadRequest, "Unknown Error")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,7 +355,7 @@ func (api *API) koAddDocuments(c *gin.Context) {
|
|||||||
var rNewDocs requestDocument
|
var rNewDocs requestDocument
|
||||||
if err := c.ShouldBindJSON(&rNewDocs); err != nil {
|
if err := c.ShouldBindJSON(&rNewDocs); err != nil {
|
||||||
log.Error("Invalid JSON Bind")
|
log.Error("Invalid JSON Bind")
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Document(s)"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid Document(s)")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,7 +363,7 @@ func (api *API) koAddDocuments(c *gin.Context) {
|
|||||||
tx, err := api.DB.DB.Begin()
|
tx, err := api.DB.DB.Begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Transaction Begin DB Error:", err)
|
log.Error("Transaction Begin DB Error:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Unknown Error"})
|
apiErrorPage(c, http.StatusBadRequest, "Unknown Error")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,7 +384,7 @@ func (api *API) koAddDocuments(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("UpsertDocument DB Error:", err)
|
log.Error("UpsertDocument DB Error:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Document"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid Document")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -391,7 +392,7 @@ func (api *API) koAddDocuments(c *gin.Context) {
|
|||||||
// Commit Transaction
|
// Commit Transaction
|
||||||
if err := tx.Commit(); err != nil {
|
if err := tx.Commit(); err != nil {
|
||||||
log.Error("Transaction Commit DB Error:", err)
|
log.Error("Transaction Commit DB Error:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Unknown Error"})
|
apiErrorPage(c, http.StatusBadRequest, "Unknown Error")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,7 +410,7 @@ func (api *API) koCheckDocumentsSync(c *gin.Context) {
|
|||||||
var rCheckDocs requestCheckDocumentSync
|
var rCheckDocs requestCheckDocumentSync
|
||||||
if err := c.ShouldBindJSON(&rCheckDocs); err != nil {
|
if err := c.ShouldBindJSON(&rCheckDocs); err != nil {
|
||||||
log.Error("Invalid JSON Bind")
|
log.Error("Invalid JSON Bind")
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid Request")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,7 +423,7 @@ func (api *API) koCheckDocumentsSync(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("UpsertDevice DB Error", err)
|
log.Error("UpsertDevice DB Error", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Device"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid Device")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,7 +434,7 @@ func (api *API) koCheckDocumentsSync(c *gin.Context) {
|
|||||||
missingDocs, err = api.DB.Queries.GetMissingDocuments(api.DB.Ctx, rCheckDocs.Have)
|
missingDocs, err = api.DB.Queries.GetMissingDocuments(api.DB.Ctx, rCheckDocs.Have)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetMissingDocuments DB Error", err)
|
log.Error("GetMissingDocuments DB Error", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid Request")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -441,7 +442,7 @@ func (api *API) koCheckDocumentsSync(c *gin.Context) {
|
|||||||
deletedDocIDs, err = api.DB.Queries.GetDeletedDocuments(api.DB.Ctx, rCheckDocs.Have)
|
deletedDocIDs, err = api.DB.Queries.GetDeletedDocuments(api.DB.Ctx, rCheckDocs.Have)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetDeletedDocuments DB Error", err)
|
log.Error("GetDeletedDocuments DB Error", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid Request")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,14 +450,14 @@ func (api *API) koCheckDocumentsSync(c *gin.Context) {
|
|||||||
jsonHaves, err := json.Marshal(rCheckDocs.Have)
|
jsonHaves, err := json.Marshal(rCheckDocs.Have)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("JSON Marshal Error", err)
|
log.Error("JSON Marshal Error", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid Request")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
wantedDocs, err := api.DB.Queries.GetWantedDocuments(api.DB.Ctx, string(jsonHaves))
|
wantedDocs, err := api.DB.Queries.GetWantedDocuments(api.DB.Ctx, string(jsonHaves))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetWantedDocuments DB Error", err)
|
log.Error("GetWantedDocuments DB Error", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid Request")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,14 +501,14 @@ func (api *API) koUploadExistingDocument(c *gin.Context) {
|
|||||||
var rDoc requestDocumentID
|
var rDoc requestDocumentID
|
||||||
if err := c.ShouldBindUri(&rDoc); err != nil {
|
if err := c.ShouldBindUri(&rDoc); err != nil {
|
||||||
log.Error("Invalid URI Bind")
|
log.Error("Invalid URI Bind")
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid Request")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fileData, err := c.FormFile("file")
|
fileData, err := c.FormFile("file")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("File Error:", err)
|
log.Error("File Error:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "File Error"})
|
apiErrorPage(c, http.StatusBadRequest, "File Error")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,7 +519,7 @@ func (api *API) koUploadExistingDocument(c *gin.Context) {
|
|||||||
|
|
||||||
if !slices.Contains([]string{".epub", ".html"}, fileExtension) {
|
if !slices.Contains([]string{".epub", ".html"}, fileExtension) {
|
||||||
log.Error("Invalid FileType:", fileExtension)
|
log.Error("Invalid FileType:", fileExtension)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Filetype"})
|
apiErrorPage(c, http.StatusBadRequest, "Invalid Filetype")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,7 +527,7 @@ func (api *API) koUploadExistingDocument(c *gin.Context) {
|
|||||||
document, err := api.DB.Queries.GetDocument(api.DB.Ctx, rDoc.DocumentID)
|
document, err := api.DB.Queries.GetDocument(api.DB.Ctx, rDoc.DocumentID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetDocument DB Error:", err)
|
log.Error("GetDocument DB Error:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Unknown Document"})
|
apiErrorPage(c, http.StatusBadRequest, "Unknown Document")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -559,7 +560,7 @@ func (api *API) koUploadExistingDocument(c *gin.Context) {
|
|||||||
err = c.SaveUploadedFile(fileData, safePath)
|
err = c.SaveUploadedFile(fileData, safePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Save Failure:", err)
|
log.Error("Save Failure:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "File Error"})
|
apiErrorPage(c, http.StatusBadRequest, "File Error")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -568,7 +569,7 @@ func (api *API) koUploadExistingDocument(c *gin.Context) {
|
|||||||
fileHash, err := getFileMD5(safePath)
|
fileHash, err := getFileMD5(safePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Hash Failure:", err)
|
log.Error("Hash Failure:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "File Error"})
|
apiErrorPage(c, http.StatusBadRequest, "File Error")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -576,7 +577,7 @@ func (api *API) koUploadExistingDocument(c *gin.Context) {
|
|||||||
wordCount, err := metadata.GetWordCount(safePath)
|
wordCount, err := metadata.GetWordCount(safePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Word Count Failure:", err)
|
log.Error("Word Count Failure:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "File Error"})
|
apiErrorPage(c, http.StatusBadRequest, "File Error")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,7 +589,7 @@ func (api *API) koUploadExistingDocument(c *gin.Context) {
|
|||||||
Words: &wordCount,
|
Words: &wordCount,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.Error("UpsertDocument DB Error:", err)
|
log.Error("UpsertDocument DB Error:", err)
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Document Error"})
|
apiErrorPage(c, http.StatusBadRequest, "Document Error")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -598,7 +599,11 @@ func (api *API) koUploadExistingDocument(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) koDemoModeJSONError(c *gin.Context) {
|
func (api *API) koDemoModeJSONError(c *gin.Context) {
|
||||||
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Not Allowed in Demo Mode"})
|
apiErrorPage(c, http.StatusUnauthorized, "Not Allowed in Demo Mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func apiErrorPage(c *gin.Context, errorCode int, errorMessage string) {
|
||||||
|
c.AbortWithStatusJSON(errorCode, gin.H{"error": errorMessage})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) sanitizeInput(val any) *string {
|
func (api *API) sanitizeInput(val any) *string {
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"embed"
|
"embed"
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pressly/goose/v3"
|
"github.com/pressly/goose/v3"
|
||||||
@ -37,7 +37,7 @@ func NewMgr(c *config.Config) *DBManager {
|
|||||||
if c.DBType == "sqlite" || c.DBType == "memory" {
|
if c.DBType == "sqlite" || c.DBType == "memory" {
|
||||||
var dbLocation string = ":memory:"
|
var dbLocation string = ":memory:"
|
||||||
if c.DBType == "sqlite" {
|
if c.DBType == "sqlite" {
|
||||||
dbLocation = path.Join(c.ConfigPath, fmt.Sprintf("%s.db", c.DBName))
|
dbLocation = filepath.Join(c.ConfigPath, fmt.Sprintf("%s.db", c.DBName))
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
Loading…
Reference in New Issue
Block a user