package dto // Правило пароля здесь и в LoginDto обязано быть ОДНИМ И ТЕМ ЖЕ. // // Пока границы расходились, панель запирала оператора снаружи после операции, // которую сама же и предлагала: форма смены пароля принимала 64 символа, а // форма входа — 32, и назначенный длинный пароль становился паролем, с которым // невозможно войти. // // Числа из тегов ушли внутрь правила `adminPassword`. Записанные тегом // `min=6,max=64` они, кроме дублирования, были ещё и неполны: тег считает // символы Unicode, а bcrypt — байты, поэтому новый пароль из 64 кириллических // букв проходил проверку формы, доходил до util.HashPassword и возвращался // оператору системной ошибкой. Отказ по байтам тегом валидатора выразить // нечем — правила длины в байтах у него нет. // // Набора символов здесь нет и не было: пароль принадлежит оператору целиком. type AdminChangePasswordDto struct { OldPassword *string `json:"oldPassword" form:"oldPassword" validate:"required,adminPassword"` NewPassword *string `json:"newPassword" form:"newPassword" validate:"required,adminPassword"` } // Normalize: пароль НЕ триммится ни в одном из полей. // // Пустое поле обязано выглядеть незаполненным и получить отказ `required`: у // поля-указателя `required` считает значение заданным по самому факту // ненулевого указателя, поэтому `{"oldPassword":""}` иначе получило бы отказ по // длине вместо «поле обязательно». // // Пробел по краям при этом остаётся частью значения. Форма входа ведёт себя так // же (LoginDto.Normalize), и иначе быть не может: пароль, назначенный здесь, // вводится там. func (d *AdminChangePasswordDto) Normalize() { emptyToNil(&d.OldPassword) emptyToNil(&d.NewPassword) }