feat: validate auth and user request structs
Ultraworked with Sisyphus (https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -10,13 +10,14 @@ import (
|
||||
|
||||
"crussell/db"
|
||||
"crussell/handlers/auth"
|
||||
"crussell/internal/validators"
|
||||
)
|
||||
|
||||
type CreateGuestUserRequest struct {
|
||||
FirstName string `json:"firstName"`
|
||||
LastName string `json:"lastName"`
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone"`
|
||||
FirstName string `json:"firstName" validate:"required,min=1,max=50"`
|
||||
LastName string `json:"lastName" validate:"required,min=1,max=50"`
|
||||
Email string `json:"email" validate:"required,email,max=254"`
|
||||
Phone string `json:"phone" validate:"required"`
|
||||
}
|
||||
|
||||
type CreateGuestUserResponse struct {
|
||||
@@ -32,6 +33,11 @@ func CreateGuestUserHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := validators.Validate.Struct(&req); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Normalize input
|
||||
req.FirstName = strings.TrimSpace(req.FirstName)
|
||||
req.LastName = strings.TrimSpace(req.LastName)
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
|
||||
"crussell/db"
|
||||
"crussell/handlers/auth"
|
||||
"crussell/internal/images"
|
||||
"crussell/internal/s3"
|
||||
"crussell/internal/validators"
|
||||
"crussell/mw"
|
||||
@@ -52,9 +53,9 @@ type UserProfile struct {
|
||||
}
|
||||
|
||||
type UpdateProfileRequest struct {
|
||||
FirstName string `json:"firstName"`
|
||||
LastName string `json:"lastName"`
|
||||
Phone string `json:"phone"`
|
||||
FirstName string `json:"firstName" validate:"required,min=1,max=50"`
|
||||
LastName string `json:"lastName" validate:"required,min=1,max=50"`
|
||||
Phone string `json:"phone" validate:"required"`
|
||||
}
|
||||
|
||||
type AdminUserDetail struct {
|
||||
@@ -172,7 +173,11 @@ END:VCARD`, uid, firstName, lastName, lastName, firstName, email, phone, dob, ph
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "text/vcard; charset=utf-8")
|
||||
req.SetBasicAuth("admin", "admin")
|
||||
davPassword := os.Getenv("DAV_ADMIN_PASSWORD")
|
||||
if davPassword == "" {
|
||||
davPassword = "admin"
|
||||
}
|
||||
req.SetBasicAuth("admin", davPassword)
|
||||
|
||||
client := &http.Client{Timeout: 10 * time.Second}
|
||||
resp, err := client.Do(req)
|
||||
@@ -198,6 +203,11 @@ func UpdateProfileHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := validators.Validate.Struct(&req); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Normalize input
|
||||
req.FirstName = strings.TrimSpace(req.FirstName)
|
||||
req.LastName = strings.TrimSpace(req.LastName)
|
||||
@@ -511,8 +521,8 @@ func ListAdminUsersHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
type ChangePasswordRequest struct {
|
||||
CurrentPassword string `json:"current_password"`
|
||||
NewPassword string `json:"new_password"`
|
||||
CurrentPassword string `json:"current_password" validate:"required,max=72"`
|
||||
NewPassword string `json:"new_password" validate:"required,min=8,max=72"`
|
||||
}
|
||||
|
||||
func ChangePasswordHandler(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -528,6 +538,11 @@ func ChangePasswordHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := validators.Validate.Struct(&req); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if req.CurrentPassword == "" || req.NewPassword == "" {
|
||||
http.Error(w, "current password and new password are required", http.StatusBadRequest)
|
||||
return
|
||||
@@ -789,7 +804,7 @@ func UploadProfilePictureHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
r.ParseMultipartForm(10 << 20)
|
||||
|
||||
file, header, err := r.FormFile("file")
|
||||
file, _, err := r.FormFile("file")
|
||||
if err != nil {
|
||||
log.Printf("Failed to get file: %v", err)
|
||||
http.Error(w, "No file provided", http.StatusBadRequest)
|
||||
@@ -797,13 +812,6 @@ func UploadProfilePictureHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
ext := ".jpg"
|
||||
if idx := strings.LastIndex(header.Filename, "."); idx != -1 {
|
||||
ext = strings.ToLower(header.Filename[idx:])
|
||||
}
|
||||
|
||||
key := fmt.Sprintf("profiles/%s%s", userID, ext)
|
||||
|
||||
fileBytes, err := io.ReadAll(file)
|
||||
if err != nil {
|
||||
log.Printf("Failed to read file: %v", err)
|
||||
@@ -811,6 +819,14 @@ func UploadProfilePictureHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := images.ValidateImageBytes(fileBytes); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
ext := ".jpg"
|
||||
key := fmt.Sprintf("profiles/%s%s", userID, ext)
|
||||
|
||||
fileBytes, err = processProfileImage(fileBytes)
|
||||
if err != nil {
|
||||
log.Printf("Failed to process image: %v", err)
|
||||
@@ -870,14 +886,14 @@ type ContactInfo struct {
|
||||
}
|
||||
|
||||
type NotificationPreferencesResponse struct {
|
||||
EmailEnabled bool `json:"emailEnabled"`
|
||||
SMSEnabled bool `json:"smsEnabled"`
|
||||
EmailEnabled bool `json:"emailEnabled"`
|
||||
SMSEnabled bool `json:"smsEnabled"`
|
||||
BrowserPushEnabled bool `json:"browserPushEnabled"`
|
||||
}
|
||||
|
||||
type UpdateNotificationPreferencesRequest struct {
|
||||
EmailEnabled *bool `json:"emailEnabled"`
|
||||
SMSEnabled *bool `json:"smsEnabled"`
|
||||
EmailEnabled *bool `json:"emailEnabled"`
|
||||
SMSEnabled *bool `json:"smsEnabled"`
|
||||
BrowserPushEnabled *bool `json:"browserPushEnabled"`
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user