[add] settings (pw & time offset), [fix] PWA issues, [fix] misc styling issues
This commit is contained in:
@@ -14,6 +14,7 @@ import (
|
||||
"reichard.io/bbank/config"
|
||||
"reichard.io/bbank/database"
|
||||
"reichard.io/bbank/graph"
|
||||
"reichard.io/bbank/utils"
|
||||
)
|
||||
|
||||
type API struct {
|
||||
@@ -74,11 +75,13 @@ func (api *API) registerWebAppRoutes() {
|
||||
render := multitemplate.NewRenderer()
|
||||
helperFuncs := template.FuncMap{
|
||||
"GetSVGGraphData": graph.GetSVGGraphData,
|
||||
"GetUTCOffsets": utils.GetUTCOffsets,
|
||||
}
|
||||
|
||||
render.AddFromFilesFuncs("login", helperFuncs, "templates/login.html")
|
||||
render.AddFromFilesFuncs("home", helperFuncs, "templates/base.html", "templates/home.html")
|
||||
render.AddFromFilesFuncs("graphs", helperFuncs, "templates/base.html", "templates/graphs.html")
|
||||
render.AddFromFilesFuncs("settings", helperFuncs, "templates/base.html", "templates/settings.html")
|
||||
render.AddFromFilesFuncs("activity", helperFuncs, "templates/base.html", "templates/activity.html")
|
||||
render.AddFromFilesFuncs("documents", helperFuncs, "templates/base.html", "templates/documents.html")
|
||||
render.AddFromFilesFuncs("document", helperFuncs, "templates/base.html", "templates/document.html")
|
||||
@@ -93,6 +96,8 @@ func (api *API) registerWebAppRoutes() {
|
||||
api.Router.POST("/register", api.authFormRegister)
|
||||
|
||||
api.Router.GET("/", api.authWebAppMiddleware, api.createAppResourcesRoute("home"))
|
||||
api.Router.GET("/settings", api.authWebAppMiddleware, api.createAppResourcesRoute("settings"))
|
||||
api.Router.POST("/settings", api.authWebAppMiddleware, api.editSettings)
|
||||
api.Router.GET("/activity", api.authWebAppMiddleware, api.createAppResourcesRoute("activity"))
|
||||
api.Router.GET("/documents", api.authWebAppMiddleware, api.createAppResourcesRoute("documents"))
|
||||
api.Router.GET("/documents/:document", api.authWebAppMiddleware, api.createAppResourcesRoute("document"))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
@@ -9,6 +10,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
argon2 "github.com/alexedwards/argon2id"
|
||||
"github.com/gabriel-vasile/mimetype"
|
||||
"github.com/gin-gonic/gin"
|
||||
log "github.com/sirupsen/logrus"
|
||||
@@ -40,6 +42,12 @@ type requestDocumentIdentify struct {
|
||||
ISBN *string `form:"isbn"`
|
||||
}
|
||||
|
||||
type requestSettingsEdit struct {
|
||||
Password *string `form:"password"`
|
||||
NewPassword *string `form:"new_password"`
|
||||
TimeOffset *string `form:"time_offset"`
|
||||
}
|
||||
|
||||
func baseResourceRoute(template string, args ...map[string]any) func(c *gin.Context) {
|
||||
variables := gin.H{"RouteName": template}
|
||||
if len(args) > 0 {
|
||||
@@ -167,6 +175,27 @@ func (api *API) createAppResourcesRoute(routeName string, args ...map[string]any
|
||||
"DatabaseInfo": database_info,
|
||||
"GraphData": read_graph_data,
|
||||
}
|
||||
} else if routeName == "settings" {
|
||||
user, err := api.DB.Queries.GetUser(api.DB.Ctx, rUser.(string))
|
||||
if err != nil {
|
||||
log.Error("[createAppResourcesRoute] GetUser DB Error:", err)
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
|
||||
return
|
||||
}
|
||||
|
||||
devices, err := api.DB.Queries.GetDevices(api.DB.Ctx, rUser.(string))
|
||||
if err != nil {
|
||||
log.Error("[createAppResourcesRoute] GetDevices DB Error:", err)
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
|
||||
return
|
||||
}
|
||||
|
||||
templateVars["Data"] = gin.H{
|
||||
"Settings": gin.H{
|
||||
"TimeOffset": *user.TimeOffset,
|
||||
},
|
||||
"Devices": devices,
|
||||
}
|
||||
} else if routeName == "login" {
|
||||
templateVars["RegistrationEnabled"] = api.Config.RegistrationEnabled
|
||||
}
|
||||
@@ -471,6 +500,88 @@ func (api *API) identifyDocument(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "document", templateVars)
|
||||
}
|
||||
|
||||
func (api *API) editSettings(c *gin.Context) {
|
||||
rUser, _ := c.Get("AuthorizedUser")
|
||||
|
||||
var rUserSettings requestSettingsEdit
|
||||
if err := c.ShouldBind(&rUserSettings); err != nil {
|
||||
log.Error("[editSettings] Invalid Form Bind")
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
|
||||
return
|
||||
}
|
||||
|
||||
// Validate Something Exists
|
||||
if rUserSettings.Password == nil && rUserSettings.NewPassword == nil && rUserSettings.TimeOffset == nil {
|
||||
log.Error("[editSettings] Missing Form Values")
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
|
||||
return
|
||||
}
|
||||
|
||||
templateVars := gin.H{
|
||||
"User": rUser,
|
||||
}
|
||||
newUserSettings := database.UpdateUserParams{
|
||||
UserID: rUser.(string),
|
||||
}
|
||||
|
||||
// Set New Password
|
||||
if rUserSettings.Password != nil && rUserSettings.NewPassword != nil {
|
||||
password := fmt.Sprintf("%x", md5.Sum([]byte(*rUserSettings.Password)))
|
||||
authorized := api.authorizeCredentials(rUser.(string), password)
|
||||
if authorized == true {
|
||||
password := fmt.Sprintf("%x", md5.Sum([]byte(*rUserSettings.NewPassword)))
|
||||
hashedPassword, err := argon2.CreateHash(password, argon2.DefaultParams)
|
||||
if err != nil {
|
||||
templateVars["PasswordErrorMessage"] = "Unknown Error"
|
||||
} else {
|
||||
templateVars["PasswordMessage"] = "Password Updated"
|
||||
newUserSettings.Password = &hashedPassword
|
||||
}
|
||||
} else {
|
||||
templateVars["PasswordErrorMessage"] = "Invalid Password"
|
||||
}
|
||||
}
|
||||
|
||||
// Set Time Offset
|
||||
if rUserSettings.TimeOffset != nil {
|
||||
templateVars["TimeOffsetMessage"] = "Time Offset Updated"
|
||||
newUserSettings.TimeOffset = rUserSettings.TimeOffset
|
||||
}
|
||||
|
||||
// Update User
|
||||
_, err := api.DB.Queries.UpdateUser(api.DB.Ctx, newUserSettings)
|
||||
if err != nil {
|
||||
log.Error("[editSettings] UpdateUser DB Error:", err)
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
|
||||
return
|
||||
}
|
||||
|
||||
// Get User
|
||||
user, err := api.DB.Queries.GetUser(api.DB.Ctx, rUser.(string))
|
||||
if err != nil {
|
||||
log.Error("[editSettings] GetUser DB Error:", err)
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
|
||||
return
|
||||
}
|
||||
|
||||
// Get Devices
|
||||
devices, err := api.DB.Queries.GetDevices(api.DB.Ctx, rUser.(string))
|
||||
if err != nil {
|
||||
log.Error("[editSettings] GetDevices DB Error:", err)
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
|
||||
return
|
||||
}
|
||||
|
||||
templateVars["Data"] = gin.H{
|
||||
"Settings": gin.H{
|
||||
"TimeOffset": *user.TimeOffset,
|
||||
},
|
||||
"Devices": devices,
|
||||
}
|
||||
|
||||
c.HTML(http.StatusOK, "settings", templateVars)
|
||||
}
|
||||
|
||||
func bindQueryParams(c *gin.Context) queryParams {
|
||||
var qParams queryParams
|
||||
c.BindQuery(&qParams)
|
||||
|
||||
@@ -24,7 +24,7 @@ func (api *API) authorizeCredentials(username string, password string) (authoriz
|
||||
return false
|
||||
}
|
||||
|
||||
if match, err := argon2.ComparePasswordAndHash(password, user.Pass); err != nil || match != true {
|
||||
if match, err := argon2.ComparePasswordAndHash(password, *user.Pass); err != nil || match != true {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -94,7 +94,6 @@ func (api *API) authFormLogin(c *gin.Context) {
|
||||
|
||||
// MD5 - KOSync Compatiblity
|
||||
password := fmt.Sprintf("%x", md5.Sum([]byte(rawPassword)))
|
||||
|
||||
if authorized := api.authorizeCredentials(username, password); authorized != true {
|
||||
c.HTML(http.StatusUnauthorized, "login", gin.H{
|
||||
"RegistrationEnabled": api.Config.RegistrationEnabled,
|
||||
@@ -140,7 +139,7 @@ func (api *API) authFormRegister(c *gin.Context) {
|
||||
|
||||
rows, err := api.DB.Queries.CreateUser(api.DB.Ctx, database.CreateUserParams{
|
||||
ID: username,
|
||||
Pass: hashedPassword,
|
||||
Pass: &hashedPassword,
|
||||
})
|
||||
|
||||
// SQL Error
|
||||
|
||||
@@ -107,7 +107,7 @@ func (api *API) createUser(c *gin.Context) {
|
||||
|
||||
rows, err := api.DB.Queries.CreateUser(api.DB.Ctx, database.CreateUserParams{
|
||||
ID: rUser.Username,
|
||||
Pass: hashedPassword,
|
||||
Pass: &hashedPassword,
|
||||
})
|
||||
if err != nil {
|
||||
log.Error("[createUser] CreateUser DB Error:", err)
|
||||
|
||||
Reference in New Issue
Block a user