hatecomputers.club/api/profiles/profiles.go

119 lines
3.8 KiB
Go

package profiles
import (
"log"
"net/http"
"strings"
"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/"
const AvatarPrefix = "/uploads/avatars/"
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)
}
}
func UpdateProfileContinuation(fileAdapter files.FilesAdapter, maxAvatarSize int, avatarPath string, avatarPrefix string) func(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain {
return func(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain {
return func(success types.Continuation, failure types.Continuation) types.ContinuationChain {
formErrors := types.BannerMessages{
Messages: []string{},
}
err := req.ParseMultipartForm(int64(maxAvatarSize))
if err != nil {
formErrors.Messages = append(formErrors.Messages, "avatar file too large")
}
if len(formErrors.Messages) == 0 {
file, _, err := req.FormFile("avatar")
if file != nil && err != nil {
formErrors.Messages = append(formErrors.Messages, "error uploading avatar")
} else if file != nil {
defer file.Close()
reader := http.MaxBytesReader(resp, file, int64(maxAvatarSize))
defer reader.Close()
_, err = fileAdapter.CreateFile(avatarPath+context.User.ID, reader)
if err != nil {
log.Println(err)
formErrors.Messages = append(formErrors.Messages, "error saving avatar (is it too big?)")
}
}
}
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)...)
if len(formErrors.Messages) == 0 {
_, err = database.SaveUser(context.DBConn, context.User)
if err != nil {
formErrors.Messages = append(formErrors.Messages, "error saving profile")
}
}
(*context.TemplateData)["Profile"] = context.User
(*context.TemplateData)["Error"] = formErrors
if len(formErrors.Messages) > 0 {
log.Println(formErrors.Messages)
resp.WriteHeader(http.StatusBadRequest)
return failure(context, req, resp)
}
formSuccess := types.BannerMessages{
Messages: []string{"profile updated"},
}
(*context.TemplateData)["Success"] = formSuccess
return success(context, req, resp)
}
}
}
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
}