mirror of
				https://github.com/yanislav-igonin/micrach
				synced 2025-11-04 02:27:02 +03:00 
			
		
		
		
	add validation on post create
This commit is contained in:
		
							parent
							
								
									55cc4a3614
								
							
						
					
					
						commit
						fb9933097b
					
				@ -244,12 +244,28 @@ func UpdateThread(c *fiber.Ctx) error {
 | 
			
		||||
	// TODO: dat shit crashes if no fields in request
 | 
			
		||||
	text := form.Value["text"][0]
 | 
			
		||||
	filesInRequest := form.File["files"]
 | 
			
		||||
	validationErrorMessage := utils.ValidatePost("", text, filesInRequest)
 | 
			
		||||
	if validationErrorMessage != "" {
 | 
			
		||||
		errorHtmlData := repositories.BadRequestHtmlData{
 | 
			
		||||
			Message: validationErrorMessage,
 | 
			
		||||
 | 
			
		||||
	validationErrors := utils.ValidatePost2("", text, filesInRequest)
 | 
			
		||||
	if validationErrors != nil {
 | 
			
		||||
		thread, err := repositories.Posts.GetThreadByPostID(threadID)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Println("error:", err)
 | 
			
		||||
			return c.Status(fiber.StatusInternalServerError).Render("pages/500", nil)
 | 
			
		||||
		}
 | 
			
		||||
		return c.Status(fiber.StatusBadRequest).Render("pages/400", errorHtmlData)
 | 
			
		||||
 | 
			
		||||
		firstPost := thread[0]
 | 
			
		||||
		captchaID := form.Value["captchaId"][0]
 | 
			
		||||
		htmlData := repositories.GetThreadHtmlData{
 | 
			
		||||
			Thread: thread,
 | 
			
		||||
			FormData: repositories.HtmlFormData{
 | 
			
		||||
				FirstPostID:     firstPost.ID,
 | 
			
		||||
				CaptchaID:       captchaID,
 | 
			
		||||
				IsCaptchaActive: config.App.IsCaptchaActive,
 | 
			
		||||
				Errors:          *validationErrors,
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return c.Render("pages/thread", htmlData)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if config.App.IsCaptchaActive {
 | 
			
		||||
 | 
			
		||||
@ -39,11 +39,19 @@ type File struct {
 | 
			
		||||
// HTML Templates Structs
 | 
			
		||||
// HTML Templates Structs
 | 
			
		||||
 | 
			
		||||
// post-form.html
 | 
			
		||||
type HtmlFormErrors struct {
 | 
			
		||||
	Title string
 | 
			
		||||
	Text  string
 | 
			
		||||
	Files string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// post-form.html
 | 
			
		||||
type HtmlFormData struct {
 | 
			
		||||
	FirstPostID     int
 | 
			
		||||
	CaptchaID       string
 | 
			
		||||
	IsCaptchaActive bool
 | 
			
		||||
	Errors          HtmlFormErrors
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// index.html
 | 
			
		||||
@ -70,11 +78,11 @@ type BadRequestHtmlData struct {
 | 
			
		||||
	Message string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const InvalidCaptchaErrorMessage = "INVALID CAPTCHA"
 | 
			
		||||
const InvalidTextOrFilesErrorMessage = "TEXT OR FILES SHOULD NOT BE EMPTY"
 | 
			
		||||
const InvalidTitleLengthErrorMessage = "TITLE SHOULD NOT EXCEED 100 CHARS"
 | 
			
		||||
const InvalidTextLengthErrorMessage = "TEXT SHOULD NOT EXCEED 1000 CHARS"
 | 
			
		||||
const InvalidFilesLengthErrorMessage = "MAXIMUM 4 FILES CAN BE UPLOADED"
 | 
			
		||||
const InvalidFileSizeErrorMessage = "FILE SIZE EXCIDED (3MB PER FILE)"
 | 
			
		||||
const InvalidFileExtErrorMessage = "AVALIABLE FILE EXT: PNG, JPG"
 | 
			
		||||
const ThreadIsArchivedErrorMessage = "THREAD IS ARCHIVED"
 | 
			
		||||
const InvalidCaptchaErrorMessage = "Invalid captcha"
 | 
			
		||||
const InvalidTextOrFilesErrorMessage = "Text or files should not be empty"
 | 
			
		||||
const InvalidTitleLengthErrorMessage = "Title should not exceed 100 chars"
 | 
			
		||||
const InvalidTextLengthErrorMessage = "Text should not exceed 1000 chars"
 | 
			
		||||
const InvalidFilesLengthErrorMessage = "Maximum 4 files can be uploaded"
 | 
			
		||||
const InvalidFileSizeErrorMessage = "File size exceeded (3MB PER FILE)"
 | 
			
		||||
const InvalidFileExtErrorMessage = "Available file ext: PNG, JPG"
 | 
			
		||||
const ThreadIsArchivedErrorMessage = "Thread is archived"
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,7 @@
 | 
			
		||||
#postForm > * {
 | 
			
		||||
.form-control {
 | 
			
		||||
  margin-bottom: 1rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.form-error-label {
 | 
			
		||||
  color: #f00;
 | 
			
		||||
}
 | 
			
		||||
@ -9,17 +9,20 @@
 | 
			
		||||
      {{ end }}
 | 
			
		||||
 | 
			
		||||
        {{ if eq .FirstPostID 0 }}
 | 
			
		||||
        <label class="form-error-label" for="title">{{ .Errors.Title }}</label>
 | 
			
		||||
        <input class="form-control" id="postTitle" placeholder="Title" name="title">
 | 
			
		||||
        {{ end }}
 | 
			
		||||
 | 
			
		||||
        <label class="form-error-label" for="text">{{ .Errors.Text }}</label>
 | 
			
		||||
        <textarea class="form-control" id="postText" rows="5" placeholder="Text" name="text"></textarea>
 | 
			
		||||
        <label class="form-error-label" for="files">{{ .Errors.Files }}</label>
 | 
			
		||||
        <input class="form-control" type="file" id="postFiles" multiple name="files">
 | 
			
		||||
        
 | 
			
		||||
        {{ if .IsCaptchaActive }}
 | 
			
		||||
        {{ template "captcha" .CaptchaID }}
 | 
			
		||||
        {{ end }}
 | 
			
		||||
 | 
			
		||||
        <div class="row">
 | 
			
		||||
        <div class="row mb-4">
 | 
			
		||||
          {{ if ne .FirstPostID 0 }}
 | 
			
		||||
          <div class="col">
 | 
			
		||||
            <input class="form-check-input" type="checkbox" value="on" id="postSage" name="sage">
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,7 @@ import (
 | 
			
		||||
	"image"
 | 
			
		||||
	"image/jpeg"
 | 
			
		||||
	"image/png"
 | 
			
		||||
	Repositories "micrach/repositories"
 | 
			
		||||
	"micrach/repositories"
 | 
			
		||||
	"mime/multipart"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
@ -70,36 +70,81 @@ func CreateThreadFolder(postID int) error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO: Delete after
 | 
			
		||||
func ValidatePost(title, text string, files []*multipart.FileHeader) string {
 | 
			
		||||
	if text == "" && len(files) == 0 {
 | 
			
		||||
		return Repositories.InvalidTextOrFilesErrorMessage
 | 
			
		||||
		return repositories.InvalidTextOrFilesErrorMessage
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len([]rune(title)) > 100 {
 | 
			
		||||
		return Repositories.InvalidTitleLengthErrorMessage
 | 
			
		||||
		return repositories.InvalidTitleLengthErrorMessage
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len([]rune(text)) > 1000 {
 | 
			
		||||
		return Repositories.InvalidTextLengthErrorMessage
 | 
			
		||||
		return repositories.InvalidTextLengthErrorMessage
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(files) > 4 {
 | 
			
		||||
		return Repositories.InvalidFilesLengthErrorMessage
 | 
			
		||||
		return repositories.InvalidFilesLengthErrorMessage
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	isFilesExtsValid := CheckFilesExt(files)
 | 
			
		||||
	if !isFilesExtsValid {
 | 
			
		||||
		return Repositories.InvalidFileExtErrorMessage
 | 
			
		||||
		return repositories.InvalidFileExtErrorMessage
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	isFilesSizesNotToBig := CheckFilesSize(files)
 | 
			
		||||
	if !isFilesSizesNotToBig {
 | 
			
		||||
		return Repositories.InvalidFileSizeErrorMessage
 | 
			
		||||
		return repositories.InvalidFileSizeErrorMessage
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ValidatePost2(title, text string, files []*multipart.FileHeader) *repositories.HtmlFormErrors {
 | 
			
		||||
	validationError := new(repositories.HtmlFormErrors)
 | 
			
		||||
	hasErrors := false
 | 
			
		||||
 | 
			
		||||
	if text == "" && len(files) == 0 {
 | 
			
		||||
		validationError.Text = repositories.InvalidTextOrFilesErrorMessage
 | 
			
		||||
		validationError.Files = repositories.InvalidTextOrFilesErrorMessage
 | 
			
		||||
		hasErrors = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len([]rune(title)) > 100 {
 | 
			
		||||
		validationError.Title = repositories.InvalidTitleLengthErrorMessage
 | 
			
		||||
		hasErrors = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len([]rune(text)) > 1000 {
 | 
			
		||||
		validationError.Text = repositories.InvalidTextLengthErrorMessage
 | 
			
		||||
		hasErrors = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(files) > 4 {
 | 
			
		||||
		validationError.Files = repositories.InvalidFilesLengthErrorMessage
 | 
			
		||||
		hasErrors = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	isFilesExtsValid := CheckFilesExt(files)
 | 
			
		||||
	if !isFilesExtsValid {
 | 
			
		||||
		validationError.Files = repositories.InvalidFileExtErrorMessage
 | 
			
		||||
		hasErrors = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	isFilesSizesNotToBig := CheckFilesSize(files)
 | 
			
		||||
	if !isFilesSizesNotToBig {
 | 
			
		||||
		validationError.Files = repositories.InvalidFileSizeErrorMessage
 | 
			
		||||
		hasErrors = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if hasErrors {
 | 
			
		||||
		return validationError
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func CheckFilesSize(files []*multipart.FileHeader) bool {
 | 
			
		||||
	for _, file := range files {
 | 
			
		||||
		if file.Size > int64(FILE_SIZE_IN_BYTES) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user