refactor(errors): handle api / app errors better
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Evan Reichard 2024-01-26 22:07:30 -05:00
parent fd8b6bcdc1
commit 8c4c1022c3
6 changed files with 316 additions and 239 deletions

View File

@ -114,8 +114,8 @@ func (api *API) registerWebAppRoutes() {
api.Router.GET("/progress", api.authWebAppMiddleware, api.appGetProgress)
api.Router.GET("/documents", api.authWebAppMiddleware, api.appGetDocuments)
api.Router.GET("/documents/:document", api.authWebAppMiddleware, api.appGetDocument)
api.Router.GET("/documents/:document/cover", api.authWebAppMiddleware, api.getDocumentCover)
api.Router.GET("/documents/:document/file", api.authWebAppMiddleware, api.downloadDocument)
api.Router.GET("/documents/:document/cover", api.authWebAppMiddleware, api.createGetCoverHandler(appErrorPage))
api.Router.GET("/documents/:document/file", api.authWebAppMiddleware, api.createDownloadDocumentHandler(appErrorPage))
api.Router.GET("/login", api.appGetLogin)
api.Router.GET("/logout", api.authWebAppMiddleware, api.appAuthLogout)
api.Router.GET("/register", api.appGetRegister)
@ -153,7 +153,7 @@ func (api *API) registerKOAPIRoutes(apiGroup *gin.RouterGroup) {
koGroup := apiGroup.Group("/ko")
// 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("/users/auth", api.authKOMiddleware, api.koAuthorizeUser)
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("/search.xml", api.authOPDSMiddleware, api.opdsSearchDescription)
opdsGroup.GET("/documents", api.authOPDSMiddleware, api.opdsDocuments)
opdsGroup.GET("/documents/:document/cover", api.authOPDSMiddleware, api.getDocumentCover)
opdsGroup.GET("/documents/:document/file", api.authOPDSMiddleware, api.downloadDocument)
opdsGroup.GET("/documents/:document/cover", api.authOPDSMiddleware, api.createGetCoverHandler(apiErrorPage))
opdsGroup.GET("/documents/:document/file", api.authOPDSMiddleware, api.createDownloadDocumentHandler(apiErrorPage))
}
func (api *API) generateTemplates() *multitemplate.Renderer {

View File

@ -13,7 +13,6 @@ import (
"mime/multipart"
"net/http"
"os"
"path"
"path/filepath"
"reflect"
"sort"
@ -154,14 +153,14 @@ func (api *API) appGetDocuments(c *gin.Context) {
})
if err != nil {
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
}
length, err := api.DB.Queries.GetDocumentsSize(api.DB.Ctx, query)
if err != nil {
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
}
@ -193,7 +192,7 @@ func (api *API) appGetDocument(c *gin.Context) {
var rDocID requestDocumentID
if err := c.ShouldBindUri(&rDocID); err != nil {
log.Error("Invalid URI Bind")
errorPage(c, http.StatusNotFound, "Invalid document.")
appErrorPage(c, http.StatusNotFound, "Invalid document.")
return
}
@ -203,7 +202,7 @@ func (api *API) appGetDocument(c *gin.Context) {
})
if err != nil {
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
}
@ -232,7 +231,7 @@ func (api *API) appGetProgress(c *gin.Context) {
progress, err := api.DB.Queries.GetProgress(api.DB.Ctx, progressFilter)
if err != nil {
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
}
@ -259,7 +258,7 @@ func (api *API) appGetActivity(c *gin.Context) {
activity, err := api.DB.Queries.GetActivity(api.DB.Ctx, activityFilter)
if err != nil {
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
}
@ -275,7 +274,7 @@ func (api *API) appGetHome(c *gin.Context) {
graphData, err := api.DB.Queries.GetDailyReadStats(api.DB.Ctx, auth.UserName)
if err != nil {
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
}
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)
if err != nil {
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
}
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)
if err != nil {
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
}
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)
if err != nil {
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
}
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)
if err != nil {
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
}
devices, err := api.DB.Queries.GetDevices(api.DB.Ctx, auth.UserName)
if err != nil {
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
}
@ -351,10 +350,10 @@ func (api *API) appGetAdminLogs(c *gin.Context) {
templateVars, _ := api.getBaseTemplateVars("admin-logs", c)
// 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)
if err != nil {
errorPage(c, http.StatusBadRequest, "Missing AnthoLume log file.")
appErrorPage(c, http.StatusBadRequest, "Missing AnthoLume log file.")
return
}
defer logFile.Close()
@ -392,7 +391,7 @@ func (api *API) appGetAdminUsers(c *gin.Context) {
users, err := api.DB.Queries.GetUsers(api.DB.Ctx)
if err != nil {
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
}
@ -411,7 +410,7 @@ func (api *API) appPerformAdminAction(c *gin.Context) {
var rAdminAction requestAdminAction
if err := c.ShouldBind(&rAdminAction); err != nil {
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
}
@ -465,7 +464,7 @@ func (api *API) appGetSearch(c *gin.Context) {
// Search
searchResults, err := search.SearchBook(*sParams.Query, *sParams.Source)
if err != nil {
errorPage(c, http.StatusInternalServerError, fmt.Sprintf("Search Error: %v", err))
appErrorPage(c, http.StatusInternalServerError, fmt.Sprintf("Search Error: %v", err))
return
}
@ -505,7 +504,7 @@ func (api *API) appGetDocumentProgress(c *gin.Context) {
var rDoc requestDocumentID
if err := c.ShouldBindUri(&rDoc); err != nil {
log.Error("Invalid URI Bind")
errorPage(c, http.StatusNotFound, "Invalid document.")
appErrorPage(c, http.StatusNotFound, "Invalid document.")
return
}
@ -516,7 +515,7 @@ func (api *API) appGetDocumentProgress(c *gin.Context) {
if err != nil && err != sql.ErrNoRows {
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
}
@ -526,7 +525,7 @@ func (api *API) appGetDocumentProgress(c *gin.Context) {
})
if err != nil {
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
}
@ -550,7 +549,7 @@ func (api *API) appGetDevices(c *gin.Context) {
if err != nil && err != sql.ErrNoRows {
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
}
@ -561,7 +560,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
var rDocUpload requestDocumentUpload
if err := c.ShouldBind(&rDocUpload); err != nil {
log.Error("Invalid Form Bind")
errorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
appErrorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
return
}
@ -574,14 +573,14 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
uploadedFile, err := rDocUpload.DocumentFile.Open()
if err != nil {
log.Error("File Error: ", err)
errorPage(c, http.StatusInternalServerError, "Unable to open file.")
appErrorPage(c, http.StatusInternalServerError, "Unable to open file.")
return
}
fileMime, err := mimetype.DetectReader(uploadedFile)
if err != nil {
log.Error("MIME Error")
errorPage(c, http.StatusInternalServerError, "Unable to detect filetype.")
appErrorPage(c, http.StatusInternalServerError, "Unable to detect filetype.")
return
}
fileExtension := fileMime.Extension()
@ -589,7 +588,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
// Validate Extension
if !slices.Contains([]string{".epub"}, fileExtension) {
log.Error("Invalid FileType: ", fileExtension)
errorPage(c, http.StatusBadRequest, "Invalid filetype.")
appErrorPage(c, http.StatusBadRequest, "Invalid filetype.")
return
}
@ -597,7 +596,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
tempFile, err := os.CreateTemp("", "book")
if err != nil {
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
}
defer os.Remove(tempFile.Name())
@ -607,7 +606,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
err = c.SaveUploadedFile(rDocUpload.DocumentFile, tempFile.Name())
if err != nil {
log.Error("File Error: ", err)
errorPage(c, http.StatusInternalServerError, "Unable to save file.")
appErrorPage(c, http.StatusInternalServerError, "Unable to save file.")
return
}
@ -615,7 +614,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
metadataInfo, err := metadata.GetMetadata(tempFile.Name())
if err != nil {
log.Warn("GetMetadata Error: ", err)
errorPage(c, http.StatusInternalServerError, "Unable to acquire file metadata.")
appErrorPage(c, http.StatusInternalServerError, "Unable to acquire file metadata.")
return
}
@ -623,7 +622,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
partialMD5, err := utils.CalculatePartialMD5(tempFile.Name())
if err != nil {
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
}
@ -638,7 +637,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
fileHash, err := getFileMD5(tempFile.Name())
if err != nil {
log.Error("MD5 Hash Failure: ", err)
errorPage(c, http.StatusInternalServerError, "Unable to calculate MD5.")
appErrorPage(c, http.StatusInternalServerError, "Unable to calculate MD5.")
return
}
@ -646,7 +645,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
wordCount, err := metadata.GetWordCount(tempFile.Name())
if err != nil {
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
}
@ -675,7 +674,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
destFile, err := os.Create(safePath)
if err != nil {
log.Error("Dest File Error: ", err)
errorPage(c, http.StatusInternalServerError, "Unable to save file.")
appErrorPage(c, http.StatusInternalServerError, "Unable to save file.")
return
}
defer destFile.Close()
@ -683,7 +682,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
// Copy File
if _, err = io.Copy(destFile, tempFile); err != nil {
log.Error("Copy Temp File Error: ", err)
errorPage(c, http.StatusInternalServerError, "Unable to save file.")
appErrorPage(c, http.StatusInternalServerError, "Unable to save file.")
return
}
@ -698,7 +697,7 @@ func (api *API) appUploadNewDocument(c *gin.Context) {
Filepath: &fileName,
}); err != nil {
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
}
@ -709,14 +708,14 @@ func (api *API) appEditDocument(c *gin.Context) {
var rDocID requestDocumentID
if err := c.ShouldBindUri(&rDocID); err != nil {
log.Error("Invalid URI Bind")
errorPage(c, http.StatusNotFound, "Invalid document.")
appErrorPage(c, http.StatusNotFound, "Invalid document.")
return
}
var rDocEdit requestDocumentEdit
if err := c.ShouldBind(&rDocEdit); err != nil {
log.Error("Invalid Form Bind")
errorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
appErrorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
return
}
@ -730,7 +729,7 @@ func (api *API) appEditDocument(c *gin.Context) {
rDocEdit.CoverGBID == nil &&
rDocEdit.CoverFile == nil {
log.Error("Missing Form Values")
errorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
appErrorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
return
}
@ -744,14 +743,14 @@ func (api *API) appEditDocument(c *gin.Context) {
uploadedFile, err := rDocEdit.CoverFile.Open()
if err != nil {
log.Error("File Error")
errorPage(c, http.StatusInternalServerError, "Unable to open file.")
appErrorPage(c, http.StatusInternalServerError, "Unable to open file.")
return
}
fileMime, err := mimetype.DetectReader(uploadedFile)
if err != nil {
log.Error("MIME Error")
errorPage(c, http.StatusInternalServerError, "Unable to detect filetype.")
appErrorPage(c, http.StatusInternalServerError, "Unable to detect filetype.")
return
}
fileExtension := fileMime.Extension()
@ -759,7 +758,7 @@ func (api *API) appEditDocument(c *gin.Context) {
// Validate Extension
if !slices.Contains([]string{".jpg", ".png"}, fileExtension) {
log.Error("Invalid FileType: ", fileExtension)
errorPage(c, http.StatusBadRequest, "Invalid filetype.")
appErrorPage(c, http.StatusBadRequest, "Invalid filetype.")
return
}
@ -771,7 +770,7 @@ func (api *API) appEditDocument(c *gin.Context) {
err = c.SaveUploadedFile(rDocEdit.CoverFile, safePath)
if err != nil {
log.Error("File Error: ", err)
errorPage(c, http.StatusInternalServerError, "Unable to save file.")
appErrorPage(c, http.StatusInternalServerError, "Unable to save file.")
return
}
@ -795,7 +794,7 @@ func (api *API) appEditDocument(c *gin.Context) {
Coverfile: coverFileName,
}); err != nil {
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
}
@ -807,18 +806,18 @@ func (api *API) appDeleteDocument(c *gin.Context) {
var rDocID requestDocumentID
if err := c.ShouldBindUri(&rDocID); err != nil {
log.Error("Invalid URI Bind")
errorPage(c, http.StatusNotFound, "Invalid document.")
appErrorPage(c, http.StatusNotFound, "Invalid document.")
return
}
changed, err := api.DB.Queries.DeleteDocument(api.DB.Ctx, rDocID.DocumentID)
if err != nil {
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
}
if changed == 0 {
log.Error("DeleteDocument DB Error")
errorPage(c, http.StatusNotFound, "Invalid document.")
appErrorPage(c, http.StatusNotFound, "Invalid document.")
return
}
@ -829,14 +828,14 @@ func (api *API) appIdentifyDocument(c *gin.Context) {
var rDocID requestDocumentID
if err := c.ShouldBindUri(&rDocID); err != nil {
log.Error("Invalid URI Bind")
errorPage(c, http.StatusNotFound, "Invalid document.")
appErrorPage(c, http.StatusNotFound, "Invalid document.")
return
}
var rDocIdentify requestDocumentIdentify
if err := c.ShouldBind(&rDocIdentify); err != nil {
log.Error("Invalid Form Bind")
errorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
appErrorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
return
}
@ -854,7 +853,7 @@ func (api *API) appIdentifyDocument(c *gin.Context) {
// Validate Values
if rDocIdentify.ISBN == nil && rDocIdentify.Title == nil && rDocIdentify.Author == nil {
log.Error("Invalid Form")
errorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
appErrorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
return
}
@ -897,7 +896,7 @@ func (api *API) appIdentifyDocument(c *gin.Context) {
})
if err != nil {
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
}
@ -911,7 +910,7 @@ func (api *API) appSaveNewDocument(c *gin.Context) {
var rDocAdd requestDocumentAdd
if err := c.ShouldBind(&rDocAdd); err != nil {
log.Error("Invalid Form Bind")
errorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
appErrorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
return
}
@ -1069,14 +1068,14 @@ func (api *API) appEditSettings(c *gin.Context) {
var rUserSettings requestSettingsEdit
if err := c.ShouldBind(&rUserSettings); err != nil {
log.Error("Invalid Form Bind")
errorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
appErrorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
return
}
// Validate Something Exists
if rUserSettings.Password == nil && rUserSettings.NewPassword == nil && rUserSettings.TimeOffset == nil {
log.Error("Missing Form Values")
errorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
appErrorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
return
}
@ -1114,7 +1113,7 @@ func (api *API) appEditSettings(c *gin.Context) {
_, err := api.DB.Queries.UpdateUser(api.DB.Ctx, newUserSettings)
if err != nil {
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
}
@ -1122,7 +1121,7 @@ func (api *API) appEditSettings(c *gin.Context) {
user, err := api.DB.Queries.GetUser(api.DB.Ctx, auth.UserName)
if err != nil {
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
}
@ -1130,7 +1129,7 @@ func (api *API) appEditSettings(c *gin.Context) {
devices, err := api.DB.Queries.GetDevices(api.DB.Ctx, auth.UserName)
if err != nil {
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
}
@ -1143,7 +1142,7 @@ func (api *API) appEditSettings(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 {
@ -1221,7 +1220,7 @@ func bindQueryParams(c *gin.Context, defaultLimit int64) queryParams {
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."
switch errorCode {
@ -1324,14 +1323,14 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
uploadedFile, err := rAdminAction.RestoreFile.Open()
if err != nil {
log.Error("File Error: ", err)
errorPage(c, http.StatusInternalServerError, "Unable to open file.")
appErrorPage(c, http.StatusInternalServerError, "Unable to open file.")
return
}
fileMime, err := mimetype.DetectReader(uploadedFile)
if err != nil {
log.Error("MIME Error")
errorPage(c, http.StatusInternalServerError, "Unable to detect filetype.")
appErrorPage(c, http.StatusInternalServerError, "Unable to detect filetype.")
return
}
fileExtension := fileMime.Extension()
@ -1339,7 +1338,7 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
// Validate Extension
if !slices.Contains([]string{".zip"}, fileExtension) {
log.Error("Invalid FileType: ", fileExtension)
errorPage(c, http.StatusBadRequest, "Invalid filetype.")
appErrorPage(c, http.StatusBadRequest, "Invalid filetype.")
return
}
@ -1347,7 +1346,7 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
tempFile, err := os.CreateTemp("", "restore")
if err != nil {
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
}
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())
if err != nil {
log.Error("File Error: ", err)
errorPage(c, http.StatusInternalServerError, "Unable to save file.")
appErrorPage(c, http.StatusInternalServerError, "Unable to save file.")
return
}
@ -1365,23 +1364,23 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
fileInfo, err := tempFile.Stat()
if err != nil {
log.Error("File Error: ", err)
errorPage(c, http.StatusInternalServerError, "Unable to read file.")
appErrorPage(c, http.StatusInternalServerError, "Unable to read file.")
return
}
// Create ZIP Reader
r, err := zip.NewReader(tempFile, fileInfo.Size())
zipReader, err := zip.NewReader(tempFile, fileInfo.Size())
if err != nil {
log.Error("ZIP Error: ", err)
errorPage(c, http.StatusInternalServerError, "Unable to read zip.")
appErrorPage(c, http.StatusInternalServerError, "Unable to read zip.")
return
}
// Validate ZIP Contents
hasDBFile := false
hasUnknownFile := false
for _, f := range r.File {
fileName := strings.TrimPrefix(f.Name, "/")
for _, file := range zipReader.File {
fileName := strings.TrimPrefix(file.Name, "/")
if fileName == "antholume.db" {
hasDBFile = true
break
@ -1394,20 +1393,20 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
// Invalid ZIP
if !hasDBFile {
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
} else if hasUnknownFile {
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
}
// 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)
if err != nil {
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
}
defer backupFile.Close()
@ -1417,7 +1416,26 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
err = api.createBackup(w, []string{"covers", "documents"})
if err != nil {
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
}
@ -1425,6 +1443,56 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
// - 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 {
ar := zip.NewWriter(w)
@ -1448,7 +1516,7 @@ func (api *API) createBackup(w io.Writer, directories []string) error {
folderName := filepath.Base(filepath.Dir(currentPath))
// Create File in Export
newF, err := ar.Create(path.Join(folderName, fileName))
newF, err := ar.Create(filepath.Join(folderName, fileName))
if err != nil {
return err
}
@ -1464,7 +1532,7 @@ func (api *API) createBackup(w io.Writer, directories []string) error {
// Get DB Path
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
dbFile, err := os.Open(dbLocation)
@ -1481,7 +1549,7 @@ func (api *API) createBackup(w io.Writer, directories []string) error {
// Backup Covers & Documents
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 {
return err
}

View File

@ -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()
return
}
@ -175,7 +175,7 @@ func (api *API) appAuthFormLogin(c *gin.Context) {
func (api *API) appAuthFormRegister(c *gin.Context) {
if !api.Config.RegistrationEnabled {
errorPage(c, http.StatusUnauthorized, "Nice try. Registration is disabled.")
appErrorPage(c, http.StatusUnauthorized, "Nice try. Registration is disabled.")
return
}
@ -236,7 +236,7 @@ func (api *API) appAuthFormRegister(c *gin.Context) {
}
session := sessions.Default(c)
if err := setSession(session, auth); err != nil {
errorPage(c, http.StatusUnauthorized, "Unauthorized.")
appErrorPage(c, http.StatusUnauthorized, "Unauthorized.")
return
}

View File

@ -11,11 +11,12 @@ import (
"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
if err := c.ShouldBindUri(&rDoc); err != nil {
log.Error("Invalid URI Bind")
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
errorFunc(c, http.StatusBadRequest, "Invalid Request")
return
}
@ -23,13 +24,13 @@ func (api *API) downloadDocument(c *gin.Context) {
document, err := api.DB.Queries.GetDocument(api.DB.Ctx, rDoc.DocumentID)
if err != nil {
log.Error("GetDocument DB Error:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Unknown Document"})
errorFunc(c, http.StatusBadRequest, "Unknown Document")
return
}
if document.Filepath == nil {
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
}
@ -40,20 +41,22 @@ func (api *API) downloadDocument(c *gin.Context) {
_, err = os.Stat(filePath)
if os.IsNotExist(err) {
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
}
// Force Download (Security)
// Force Download
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filepath.Base(*document.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
if err := c.ShouldBindUri(&rDoc); err != nil {
log.Error("Invalid URI Bind")
errorPage(c, http.StatusNotFound, "Invalid cover.")
errorFunc(c, http.StatusNotFound, "Invalid cover.")
return
}
@ -61,7 +64,7 @@ func (api *API) getDocumentCover(c *gin.Context) {
document, err := api.DB.Queries.GetDocument(api.DB.Ctx, rDoc.DocumentID)
if err != nil {
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
}
@ -137,4 +140,5 @@ func (api *API) getDocumentCover(c *gin.Context) {
coverFilePath := filepath.Join(coverDir, coverFile)
c.File(coverFilePath)
}
}

View File

@ -90,20 +90,20 @@ func (api *API) koCreateUser(c *gin.Context) {
var rUser requestUser
if err := c.ShouldBindJSON(&rUser); err != nil {
log.Error("Invalid JSON Bind")
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid User Data"})
apiErrorPage(c, http.StatusBadRequest, "Invalid User Data")
return
}
if rUser.Username == "" || rUser.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
}
hashedPassword, err := argon2.CreateHash(rUser.Password, argon2.DefaultParams)
if err != nil {
log.Error("Argon2 Hash Failure:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Unknown Error"})
apiErrorPage(c, http.StatusBadRequest, "Unknown Error")
return
}
@ -113,13 +113,14 @@ func (api *API) koCreateUser(c *gin.Context) {
})
if err != nil {
log.Error("CreateUser DB Error:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid User Data"})
apiErrorPage(c, http.StatusBadRequest, "Invalid User Data")
return
}
// User Exists
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
}
@ -137,7 +138,7 @@ func (api *API) koSetProgress(c *gin.Context) {
var rPosition requestPosition
if err := c.ShouldBindJSON(&rPosition); err != nil {
log.Error("Invalid JSON Bind")
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Progress Data"})
apiErrorPage(c, http.StatusBadRequest, "Invalid Progress Data")
return
}
@ -168,7 +169,7 @@ func (api *API) koSetProgress(c *gin.Context) {
})
if err != nil {
log.Error("UpdateProgress DB Error:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
apiErrorPage(c, http.StatusBadRequest, "Invalid Request")
return
}
@ -187,7 +188,7 @@ func (api *API) koGetProgress(c *gin.Context) {
var rDocID requestDocumentID
if err := c.ShouldBindUri(&rDocID); err != nil {
log.Error("Invalid URI Bind")
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
apiErrorPage(c, http.StatusBadRequest, "Invalid Request")
return
}
@ -202,7 +203,7 @@ func (api *API) koGetProgress(c *gin.Context) {
return
} else if err != nil {
log.Error("GetDocumentProgress DB Error:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Document"})
apiErrorPage(c, http.StatusBadRequest, "Invalid Document")
return
}
@ -224,7 +225,7 @@ func (api *API) koAddActivities(c *gin.Context) {
var rActivity requestActivity
if err := c.ShouldBindJSON(&rActivity); err != nil {
log.Error("Invalid JSON Bind")
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Activity"})
apiErrorPage(c, http.StatusBadRequest, "Invalid Activity")
return
}
@ -232,7 +233,7 @@ func (api *API) koAddActivities(c *gin.Context) {
tx, err := api.DB.DB.Begin()
if err != nil {
log.Error("Transaction Begin DB Error:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Unknown Error"})
apiErrorPage(c, http.StatusBadRequest, "Unknown Error")
return
}
@ -253,7 +254,7 @@ func (api *API) koAddActivities(c *gin.Context) {
ID: doc,
}); err != nil {
log.Error("UpsertDocument DB Error:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Document"})
apiErrorPage(c, http.StatusBadRequest, "Invalid Document")
return
}
}
@ -266,7 +267,7 @@ func (api *API) koAddActivities(c *gin.Context) {
LastSynced: time.Now().UTC().Format(time.RFC3339),
}); err != nil {
log.Error("UpsertDevice DB Error:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Device"})
apiErrorPage(c, http.StatusBadRequest, "Invalid Device")
return
}
@ -282,7 +283,7 @@ func (api *API) koAddActivities(c *gin.Context) {
EndPercentage: float64(item.Page+1) / float64(item.Pages),
}); err != nil {
log.Error("AddActivity DB Error:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Activity"})
apiErrorPage(c, http.StatusBadRequest, "Invalid Activity")
return
}
}
@ -290,7 +291,7 @@ func (api *API) koAddActivities(c *gin.Context) {
// Commit Transaction
if err := tx.Commit(); err != nil {
log.Error("Transaction Commit DB Error:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Unknown Error"})
apiErrorPage(c, http.StatusBadRequest, "Unknown Error")
return
}
@ -308,7 +309,7 @@ func (api *API) koCheckActivitySync(c *gin.Context) {
var rCheckActivity requestCheckActivitySync
if err := c.ShouldBindJSON(&rCheckActivity); err != nil {
log.Error("Invalid JSON Bind")
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
apiErrorPage(c, http.StatusBadRequest, "Invalid Request")
return
}
@ -320,7 +321,7 @@ func (api *API) koCheckActivitySync(c *gin.Context) {
LastSynced: time.Now().UTC().Format(time.RFC3339),
}); err != nil {
log.Error("UpsertDevice DB Error", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Device"})
apiErrorPage(c, http.StatusBadRequest, "Invalid Device")
return
}
@ -333,7 +334,7 @@ func (api *API) koCheckActivitySync(c *gin.Context) {
lastActivity = time.UnixMilli(0).Format(time.RFC3339)
} else if err != nil {
log.Error("GetLastActivity DB Error:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Unknown Error"})
apiErrorPage(c, http.StatusBadRequest, "Unknown Error")
return
}
@ -341,7 +342,7 @@ func (api *API) koCheckActivitySync(c *gin.Context) {
parsedTime, err := time.Parse(time.RFC3339, lastActivity)
if err != nil {
log.Error("Time Parse Error:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Unknown Error"})
apiErrorPage(c, http.StatusBadRequest, "Unknown Error")
return
}
@ -354,7 +355,7 @@ func (api *API) koAddDocuments(c *gin.Context) {
var rNewDocs requestDocument
if err := c.ShouldBindJSON(&rNewDocs); err != nil {
log.Error("Invalid JSON Bind")
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Document(s)"})
apiErrorPage(c, http.StatusBadRequest, "Invalid Document(s)")
return
}
@ -362,7 +363,7 @@ func (api *API) koAddDocuments(c *gin.Context) {
tx, err := api.DB.DB.Begin()
if err != nil {
log.Error("Transaction Begin DB Error:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Unknown Error"})
apiErrorPage(c, http.StatusBadRequest, "Unknown Error")
return
}
@ -383,7 +384,7 @@ func (api *API) koAddDocuments(c *gin.Context) {
})
if err != nil {
log.Error("UpsertDocument DB Error:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Document"})
apiErrorPage(c, http.StatusBadRequest, "Invalid Document")
return
}
}
@ -391,7 +392,7 @@ func (api *API) koAddDocuments(c *gin.Context) {
// Commit Transaction
if err := tx.Commit(); err != nil {
log.Error("Transaction Commit DB Error:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Unknown Error"})
apiErrorPage(c, http.StatusBadRequest, "Unknown Error")
return
}
@ -409,7 +410,7 @@ func (api *API) koCheckDocumentsSync(c *gin.Context) {
var rCheckDocs requestCheckDocumentSync
if err := c.ShouldBindJSON(&rCheckDocs); err != nil {
log.Error("Invalid JSON Bind")
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
apiErrorPage(c, http.StatusBadRequest, "Invalid Request")
return
}
@ -422,7 +423,7 @@ func (api *API) koCheckDocumentsSync(c *gin.Context) {
})
if err != nil {
log.Error("UpsertDevice DB Error", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Device"})
apiErrorPage(c, http.StatusBadRequest, "Invalid Device")
return
}
@ -433,7 +434,7 @@ func (api *API) koCheckDocumentsSync(c *gin.Context) {
missingDocs, err = api.DB.Queries.GetMissingDocuments(api.DB.Ctx, rCheckDocs.Have)
if err != nil {
log.Error("GetMissingDocuments DB Error", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
apiErrorPage(c, http.StatusBadRequest, "Invalid Request")
return
}
@ -441,7 +442,7 @@ func (api *API) koCheckDocumentsSync(c *gin.Context) {
deletedDocIDs, err = api.DB.Queries.GetDeletedDocuments(api.DB.Ctx, rCheckDocs.Have)
if err != nil {
log.Error("GetDeletedDocuments DB Error", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
apiErrorPage(c, http.StatusBadRequest, "Invalid Request")
return
}
@ -449,14 +450,14 @@ func (api *API) koCheckDocumentsSync(c *gin.Context) {
jsonHaves, err := json.Marshal(rCheckDocs.Have)
if err != nil {
log.Error("JSON Marshal Error", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
apiErrorPage(c, http.StatusBadRequest, "Invalid Request")
return
}
wantedDocs, err := api.DB.Queries.GetWantedDocuments(api.DB.Ctx, string(jsonHaves))
if err != nil {
log.Error("GetWantedDocuments DB Error", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
apiErrorPage(c, http.StatusBadRequest, "Invalid Request")
return
}
@ -500,14 +501,14 @@ func (api *API) koUploadExistingDocument(c *gin.Context) {
var rDoc requestDocumentID
if err := c.ShouldBindUri(&rDoc); err != nil {
log.Error("Invalid URI Bind")
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
apiErrorPage(c, http.StatusBadRequest, "Invalid Request")
return
}
fileData, err := c.FormFile("file")
if err != nil {
log.Error("File Error:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "File Error"})
apiErrorPage(c, http.StatusBadRequest, "File Error")
return
}
@ -518,7 +519,7 @@ func (api *API) koUploadExistingDocument(c *gin.Context) {
if !slices.Contains([]string{".epub", ".html"}, fileExtension) {
log.Error("Invalid FileType:", fileExtension)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Filetype"})
apiErrorPage(c, http.StatusBadRequest, "Invalid Filetype")
return
}
@ -526,7 +527,7 @@ func (api *API) koUploadExistingDocument(c *gin.Context) {
document, err := api.DB.Queries.GetDocument(api.DB.Ctx, rDoc.DocumentID)
if err != nil {
log.Error("GetDocument DB Error:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Unknown Document"})
apiErrorPage(c, http.StatusBadRequest, "Unknown Document")
return
}
@ -559,7 +560,7 @@ func (api *API) koUploadExistingDocument(c *gin.Context) {
err = c.SaveUploadedFile(fileData, safePath)
if err != nil {
log.Error("Save Failure:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "File Error"})
apiErrorPage(c, http.StatusBadRequest, "File Error")
return
}
}
@ -568,7 +569,7 @@ func (api *API) koUploadExistingDocument(c *gin.Context) {
fileHash, err := getFileMD5(safePath)
if err != nil {
log.Error("Hash Failure:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "File Error"})
apiErrorPage(c, http.StatusBadRequest, "File Error")
return
}
@ -576,7 +577,7 @@ func (api *API) koUploadExistingDocument(c *gin.Context) {
wordCount, err := metadata.GetWordCount(safePath)
if err != nil {
log.Error("Word Count Failure:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "File Error"})
apiErrorPage(c, http.StatusBadRequest, "File Error")
return
}
@ -588,7 +589,7 @@ func (api *API) koUploadExistingDocument(c *gin.Context) {
Words: &wordCount,
}); err != nil {
log.Error("UpsertDocument DB Error:", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Document Error"})
apiErrorPage(c, http.StatusBadRequest, "Document Error")
return
}
@ -598,7 +599,11 @@ func (api *API) koUploadExistingDocument(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 {

View File

@ -6,7 +6,7 @@ import (
"embed"
_ "embed"
"fmt"
"path"
"path/filepath"
"time"
"github.com/pressly/goose/v3"
@ -37,7 +37,7 @@ func NewMgr(c *config.Config) *DBManager {
if c.DBType == "sqlite" || c.DBType == "memory" {
var dbLocation string = ":memory:"
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