frontend: disabled button while processing password reset

This commit is contained in:
Alex
2025-02-28 08:51:35 +01:00
parent 8137f121ed
commit 9c9430ca9c
92 changed files with 37 additions and 17 deletions

View File

@@ -0,0 +1,53 @@
package validation
import (
"GoMembership/internal/models"
"time"
"github.com/go-playground/validator/v10"
)
func validateDriverslicence(sl validator.StructLevel) {
dl := sl.Current().Interface().(models.User).Licence
// if !vValidateLicence(dl.Number) {
if dl.Number == "" {
sl.ReportError(dl.Number, "licence_number", "", "invalid", "")
}
if dl.IssuedDate.After(time.Now()) {
sl.ReportError(dl.IssuedDate, "issued_date", "", "invalid", "")
}
if dl.ExpirationDate.Before(time.Now().AddDate(0, 0, 3)) {
sl.ReportError(dl.ExpirationDate, "expiration_date", "", "too_soon", "")
}
}
// seems like not every country has to have an licence id and it seems that germany changed their id generation type..
// func validateLicence(fieldValue string) bool {
// if len(fieldValue) != 11 {
// return false
// }
// id, tenthChar := string(fieldValue[:9]), string(fieldValue[9])
// if tenthChar == "X" {
// tenthChar = "10"
// }
// tenthValue, _ := strconv.ParseInt(tenthChar, 10, 8)
// // for readability
// weights := []int{9, 8, 7, 6, 5, 4, 3, 2, 1}
// sum := 0
// for i := 0; i < 9; i++ {
// char := string(id[i])
// value, _ := strconv.ParseInt(char, 36, 64)
// sum += int(value) * weights[i]
// }
// calcCheckDigit := sum % 11
// if calcCheckDigit != int(tenthValue) {
// return false
// }
// return true
// }

View File

@@ -0,0 +1,27 @@
package validation
import (
"GoMembership/internal/models"
"github.com/go-playground/validator/v10"
"github.com/jbub/banking/iban"
"github.com/jbub/banking/swift"
)
func validateBankAccount(sl validator.StructLevel) {
ba := sl.Current().Interface().(models.User).BankAccount
if !ibanValidator(ba.IBAN) {
sl.ReportError(ba.IBAN, "IBAN", "BankAccount.IBAN", "required", "")
}
if ba.BIC != "" && !bicValidator(ba.BIC) {
sl.ReportError(ba.IBAN, "IBAN", "BankAccount.IBAN", "required", "")
}
}
func ibanValidator(fieldValue string) bool {
return iban.Validate(fieldValue) == nil
}
func bicValidator(fieldValue string) bool {
return swift.Validate(fieldValue) == nil
}

View File

@@ -0,0 +1,34 @@
package validation
import (
"regexp"
"strings"
"github.com/go-playground/validator/v10"
)
var xssPatterns = []*regexp.Regexp{
regexp.MustCompile(`(?i)<script`),
regexp.MustCompile(`(?i)javascript:`),
regexp.MustCompile(`(?i)on\w+\s*=`),
regexp.MustCompile(`(?i)(vbscript|data):`),
regexp.MustCompile(`(?i)<(iframe|object|embed|applet)`),
regexp.MustCompile(`(?i)expression\s*\(`),
regexp.MustCompile(`(?i)url\s*\(`),
regexp.MustCompile(`(?i)<\?`),
regexp.MustCompile(`(?i)<%`),
regexp.MustCompile(`(?i)<!\[CDATA\[`),
regexp.MustCompile(`(?i)<(svg|animate)`),
regexp.MustCompile(`(?i)<(audio|video|source)`),
regexp.MustCompile(`(?i)base64`),
}
func ValidateSafeContent(fl validator.FieldLevel) bool {
input := strings.ToLower(fl.Field().String())
for _, pattern := range xssPatterns {
if pattern.MatchString(input) {
return false
}
}
return true
}

View File

@@ -0,0 +1,42 @@
package validation
import (
"GoMembership/internal/models"
"GoMembership/internal/repositories"
"GoMembership/pkg/errors"
"GoMembership/pkg/logger"
"github.com/go-playground/validator/v10"
)
func validateMembership(sl validator.StructLevel) {
membership := sl.Current().Interface().(models.User).Membership
if membership.SubscriptionModel.RequiredMembershipField != "" {
switch membership.SubscriptionModel.RequiredMembershipField {
case "ParentMembershipID":
if err := CheckParentMembershipID(membership); err != nil {
logger.Error.Printf("Error ParentMembershipValidation: %v", err.Error())
sl.ReportError(membership.ParentMembershipID, membership.SubscriptionModel.RequiredMembershipField,
"RequiredMembershipField", "invalid", "")
}
default:
logger.Error.Printf("Error no matching RequiredMembershipField: %v", errors.ErrInvalidValue.Error())
sl.ReportError(membership.ParentMembershipID, membership.SubscriptionModel.RequiredMembershipField,
"RequiredMembershipField", "not_implemented", "")
}
}
}
func CheckParentMembershipID(membership models.Membership) error {
if membership.ParentMembershipID == 0 {
return errors.ValErrParentIDNotSet
} else {
_, err := repositories.GetUserByID(&membership.ParentMembershipID)
if err != nil {
return errors.ValErrParentIDNotFound
}
}
return nil
}

View File

@@ -0,0 +1,20 @@
package validation
import (
"GoMembership/internal/models"
"github.com/gin-gonic/gin/binding"
"github.com/go-playground/validator/v10"
)
func SetupValidators() {
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
// Register custom validators
v.RegisterValidation("safe_content", ValidateSafeContent)
// Register struct-level validations
v.RegisterStructValidation(validateUser, models.User{})
v.RegisterStructValidation(ValidateSubscription, models.SubscriptionModel{})
}
}

View File

@@ -0,0 +1,46 @@
package validation
import (
"GoMembership/internal/models"
"GoMembership/internal/repositories"
"github.com/go-playground/validator/v10"
)
// ValidateNewSubscription validates a new subscription model being created
func ValidateSubscription(sl validator.StructLevel) {
subscription := sl.Current().Interface().(models.SubscriptionModel)
if subscription.Name == "" {
sl.ReportError(subscription.Name, "Name", "name", "required", "")
}
if sl.Parent().Type().Name() == "MembershipData" {
// This is modifying a subscription directly
if subscription.Details == "" {
sl.ReportError(subscription.Details, "Details", "details", "required", "")
}
if subscription.MonthlyFee < 0 {
sl.ReportError(subscription.MonthlyFee, "MonthlyFee", "monthly_fee", "gte", "0")
}
if subscription.HourlyRate < 0 {
sl.ReportError(subscription.HourlyRate, "HourlyRate", "hourly_rate", "gte", "0")
}
if subscription.IncludedPerYear < 0 {
sl.ReportError(subscription.IncludedPerYear, "IncludedPerYear", "included_hours_per_year", "gte", "0")
}
if subscription.IncludedPerMonth < 0 {
sl.ReportError(subscription.IncludedPerMonth, "IncludedPerMonth", "included_hours_per_month", "gte", "0")
}
} else {
// This is a nested probably user struct. We are only checking if the model exists
existingSubscription, err := repositories.GetSubscriptionByName(&subscription.Name)
if err != nil || existingSubscription == nil {
sl.ReportError(subscription.Name, "Subscription_Name", "name", "exists", "")
}
}
}

View File

@@ -0,0 +1,49 @@
package validation
import (
"GoMembership/internal/constants"
"GoMembership/internal/models"
"GoMembership/internal/repositories"
"GoMembership/pkg/logger"
"time"
"github.com/go-playground/validator/v10"
)
func validateUser(sl validator.StructLevel) {
user := sl.Current().Interface().(models.User)
isSuper := user.RoleID >= constants.Roles.Admin
if user.RoleID > constants.Roles.Member && user.Password == "" {
passwordExists, err := repositories.PasswordExists(&user.ID)
if err != nil || !passwordExists {
logger.Error.Printf("Error checking password exists for user %v: %v", user.Email, err)
sl.ReportError(user.Password, "Password", "password", "required", "")
}
}
// Validate User > 18 years old
if user.DateOfBirth.After(time.Now().AddDate(-18, 0, 0)) {
sl.ReportError(user.DateOfBirth, "DateOfBirth", "dateofbirth", "age", "")
}
// validate subscriptionModel
if user.Membership.SubscriptionModel.Name == "" {
sl.ReportError(user.Membership.SubscriptionModel.Name, "SubscriptionModel.Name", "name", "required", "")
} else {
selectedModel, err := repositories.GetSubscriptionByName(&user.Membership.SubscriptionModel.Name)
if err != nil {
logger.Error.Printf("Error finding subscription model for user %v: %v", user.Email, err)
sl.ReportError(user.Membership.SubscriptionModel.Name, "SubscriptionModel.Name", "name", "invalid", "")
} else {
user.Membership.SubscriptionModel = *selectedModel
}
}
validateMembership(sl)
if !isSuper {
validateBankAccount(sl)
if user.Licence != nil {
validateDriverslicence(sl)
}
}
}