feat: add ability to force email verification (#1837)

This commit is contained in:
Elias Schneider
2026-10-13 22:04:33 +02:00
committed by GitHub
parent eb8ea6bed2
commit 0ffeb170cf
81 changed files with 2310 additions and 263 deletions
+1 -1
View File
@@ -59,7 +59,7 @@ type AppConfigUpdateDto struct {
EmailOneTimeAccessAsUnauthenticatedEnabled string `json:"emailOneTimeAccessAsUnauthenticatedEnabled" binding:"required,boolean_string"`
EmailLoginNotificationMode string `json:"emailLoginNotificationMode" binding:"required,oneof=disabled always ipAndUserAgent browserRecognition"`
EmailApiKeyExpirationEnabled string `json:"emailApiKeyExpirationEnabled" binding:"required,boolean_string"`
EmailVerificationEnabled string `json:"emailVerificationEnabled" binding:"required,boolean_string"`
EmailVerification string `json:"emailVerification" binding:"required,oneof=disabled optional required,email_verification"`
CIMDURLAllowlist string `json:"cimdUrlAllowlist" binding:"omitempty,cimd_url_allowlist"`
AutoCreateOIDCClientSecret string `json:"autoCreateOidcClientSecret" binding:"required,boolean_string"`
}
+4
View File
@@ -4,6 +4,8 @@ import (
"errors"
"github.com/gin-gonic/gin/binding"
datatype "github.com/pocket-id/pocket-id/backend/internal/model/types"
)
type UserDto struct {
@@ -20,6 +22,8 @@ type UserDto struct {
UserGroups []UserGroupMinimalDto `json:"userGroups"`
LdapID *string `json:"ldapId"`
Disabled bool `json:"disabled"`
EmailVerificationDeadline *datatype.DateTime `json:"emailVerificationDeadline,omitempty"`
}
type UserCreateDto struct {
+11
View File
@@ -92,6 +92,15 @@ func init() {
"integer_string": func(fl validator.FieldLevel) bool {
return validateIntegerString(fl.Field().String())
},
"email_verification": func(fl validator.FieldLevel) bool {
// Required verification needs emails that aren't trusted by default and the SMTP host and sender address without which no verification link can be sent
parent := fl.Parent()
return fl.Field().String() != "required" ||
(parent.FieldByName("RequireUserEmail").String() == "true" &&
parent.FieldByName("EmailsVerified").String() == "false" &&
parent.FieldByName("SmtpHost").String() != "" &&
parent.FieldByName("SmtpFrom").String() != "")
},
}
for k, v := range validators {
err := engine.RegisterValidation(k, v)
@@ -182,6 +191,8 @@ func ValidationErrorDetails(validationError validator.FieldError) (string, strin
return "invalid_format", "must be either true or false"
case "integer_string":
return "invalid_format", "must be an integer"
case "email_verification":
return "invalid_configuration", "requires user emails, an SMTP host and sender address, and forbids emails verified by default"
default:
return validationError.Tag(), "is invalid"
}