2024-04-08 19:04:19 -04:00
|
|
|
package profiles
|
|
|
|
|
|
|
|
import (
|
|
|
|
"log"
|
|
|
|
"net/http"
|
2024-04-09 18:29:52 -04:00
|
|
|
"strings"
|
2024-04-08 19:04:19 -04:00
|
|
|
|
|
|
|
"git.hatecomputers.club/hatecomputers/hatecomputers.club/adapters/files"
|
|
|
|
"git.hatecomputers.club/hatecomputers/hatecomputers.club/api/types"
|
|
|
|
"git.hatecomputers.club/hatecomputers/hatecomputers.club/database"
|
|
|
|
)
|
|
|
|
|
|
|
|
const MaxAvatarSize = 1024 * 1024 * 2 // 2MB
|
|
|
|
const AvatarPath = "avatars/"
|
2024-04-08 19:15:31 -04:00
|
|
|
const AvatarPrefix = "/uploads/avatars/"
|
2024-04-08 19:04:19 -04:00
|
|
|
|
|
|
|
func GetProfileContinuation(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain {
|
|
|
|
return func(success types.Continuation, failure types.Continuation) types.ContinuationChain {
|
|
|
|
if context.User == nil {
|
|
|
|
return failure(context, req, resp)
|
|
|
|
}
|
|
|
|
|
|
|
|
(*context.TemplateData)["Profile"] = context.User
|
|
|
|
return success(context, req, resp)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-08 19:15:31 -04:00
|
|
|
func UpdateProfileContinuation(fileAdapter files.FilesAdapter, maxAvatarSize int, avatarPath string, avatarPrefix string) func(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain {
|
2024-04-08 19:04:19 -04:00
|
|
|
return func(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain {
|
|
|
|
return func(success types.Continuation, failure types.Continuation) types.ContinuationChain {
|
2024-04-09 18:29:52 -04:00
|
|
|
formErrors := types.BannerMessages{
|
|
|
|
Messages: []string{},
|
2024-04-08 19:04:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
err := req.ParseMultipartForm(int64(maxAvatarSize))
|
|
|
|
if err != nil {
|
2024-04-09 18:29:52 -04:00
|
|
|
formErrors.Messages = append(formErrors.Messages, "avatar file too large")
|
2024-04-08 19:04:19 -04:00
|
|
|
}
|
|
|
|
|
2024-04-09 18:29:52 -04:00
|
|
|
if len(formErrors.Messages) == 0 {
|
2024-04-08 19:04:19 -04:00
|
|
|
file, _, err := req.FormFile("avatar")
|
2024-04-09 18:29:52 -04:00
|
|
|
if file != nil && err != nil {
|
|
|
|
formErrors.Messages = append(formErrors.Messages, "error uploading avatar")
|
|
|
|
} else if file != nil {
|
2024-04-08 19:04:19 -04:00
|
|
|
defer file.Close()
|
2024-04-09 18:29:52 -04:00
|
|
|
reader := http.MaxBytesReader(resp, file, int64(maxAvatarSize))
|
|
|
|
defer reader.Close()
|
2024-04-08 19:04:19 -04:00
|
|
|
|
2024-04-09 18:29:52 -04:00
|
|
|
_, err = fileAdapter.CreateFile(avatarPath+context.User.ID, reader)
|
2024-04-08 19:04:19 -04:00
|
|
|
if err != nil {
|
|
|
|
log.Println(err)
|
2024-04-09 18:29:52 -04:00
|
|
|
formErrors.Messages = append(formErrors.Messages, "error saving avatar (is it too big?)")
|
2024-04-08 19:04:19 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-09 18:29:52 -04:00
|
|
|
context.User.Bio = strings.Trim(req.FormValue("bio"), "\n")
|
|
|
|
context.User.Pronouns = req.FormValue("pronouns")
|
|
|
|
context.User.Location = req.FormValue("location")
|
|
|
|
context.User.Website = req.FormValue("website")
|
|
|
|
context.User.Avatar = avatarPrefix + context.User.ID
|
|
|
|
formErrors.Messages = append(formErrors.Messages, validateProfileUpdate(context.User)...)
|
2024-04-08 19:04:19 -04:00
|
|
|
|
2024-04-09 18:29:52 -04:00
|
|
|
if len(formErrors.Messages) == 0 {
|
2024-04-08 19:04:19 -04:00
|
|
|
_, err = database.SaveUser(context.DBConn, context.User)
|
|
|
|
if err != nil {
|
2024-04-09 18:29:52 -04:00
|
|
|
formErrors.Messages = append(formErrors.Messages, "error saving profile")
|
2024-04-08 19:04:19 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
(*context.TemplateData)["Profile"] = context.User
|
2024-04-09 18:29:52 -04:00
|
|
|
(*context.TemplateData)["Error"] = formErrors
|
2024-04-08 19:04:19 -04:00
|
|
|
|
2024-04-09 18:29:52 -04:00
|
|
|
if len(formErrors.Messages) > 0 {
|
|
|
|
log.Println(formErrors.Messages)
|
2024-04-08 19:04:19 -04:00
|
|
|
|
|
|
|
resp.WriteHeader(http.StatusBadRequest)
|
|
|
|
return failure(context, req, resp)
|
|
|
|
}
|
|
|
|
|
2024-04-09 18:29:52 -04:00
|
|
|
formSuccess := types.BannerMessages{
|
|
|
|
Messages: []string{"profile updated"},
|
|
|
|
}
|
|
|
|
(*context.TemplateData)["Success"] = formSuccess
|
2024-04-08 19:04:19 -04:00
|
|
|
return success(context, req, resp)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-04-09 18:29:52 -04:00
|
|
|
|
|
|
|
func validateProfileUpdate(user *database.User) []string {
|
|
|
|
errors := []string{}
|
|
|
|
|
|
|
|
if (!strings.HasPrefix(user.Website, "https://") && !strings.HasPrefix(user.Website, "http://")) || len(user.Website) < 8 {
|
|
|
|
errors = append(errors, "website must be a valid URL")
|
|
|
|
}
|
|
|
|
if len(user.Website) > 64 {
|
|
|
|
errors = append(errors, "website cannot be longer than 64 characters")
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(user.Pronouns) > 64 {
|
|
|
|
errors = append(errors, "pronouns cannot be longer than 64 characters")
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(user.Bio) > 128 {
|
|
|
|
errors = append(errors, "bio cannot be longer than 128 characters")
|
|
|
|
}
|
|
|
|
|
|
|
|
newLines := strings.Count(user.Bio, "\n")
|
|
|
|
if newLines > 8 {
|
|
|
|
errors = append(errors, "message cannot contain more than 8 new lines")
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(user.Location) > 32 {
|
|
|
|
errors = append(errors, "location cannot be longer than 64 characters")
|
|
|
|
}
|
|
|
|
|
|
|
|
return errors
|
|
|
|
}
|