diff --git a/CHANGES.md b/CHANGES.md index 486266b23..280690f31 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -39,6 +39,9 @@ - Fix scroll on viewer comment list [Taiga #5563](https://tree.taiga.io/project/penpot/issue/5563) - Fix context menu z-index [Taiga #5561](https://tree.taiga.io/project/penpot/issue/5561) - Fix select all checkbox on shared link config [Taiga #5566](https://tree.taiga.io/project/penpot/issue/5566) +- Fix validation on full name input on account creation [Taiga #5516](https://tree.taiga.io/project/penpot/issue/5516) +- Fix validation on team name input [Taiga #5510](https://tree.taiga.io/project/penpot/issue/5510) + ### :arrow_up: Deps updates diff --git a/frontend/src/app/main/ui/auth/recovery.cljs b/frontend/src/app/main/ui/auth/recovery.cljs index 3f752f7f6..397edc4d9 100644 --- a/frontend/src/app/main/ui/auth/recovery.cljs +++ b/frontend/src/app/main/ui/auth/recovery.cljs @@ -56,7 +56,9 @@ (mf/defc recovery-form [{:keys [params] :as props}] (let [form (fm/use-form :spec ::recovery-form - :validators [password-equality] + :validators [password-equality + (fm/validate-not-empty :password-1 (tr "auth.password-not-empty")) + (fm/validate-not-empty :password-2 (tr "auth.password-not-empty"))] :initial params)] [:& fm/form {:on-submit on-submit :form form} diff --git a/frontend/src/app/main/ui/auth/register.cljs b/frontend/src/app/main/ui/auth/register.cljs index 37314093b..01986eccb 100644 --- a/frontend/src/app/main/ui/auth/register.cljs +++ b/frontend/src/app/main/ui/auth/register.cljs @@ -22,7 +22,6 @@ [app.util.router :as rt] [beicon.core :as rx] [cljs.spec.alpha :as s] - [cuerdas.core :as str] [rumext.v2 :as mf])) (mf/defc demo-warning @@ -46,13 +45,6 @@ (= code ::us/email) (assoc :message (tr "errors.email-invalid")))))))) -(defn- validate-password - [errors data] - (let [password (-> data :password str/trim)] - (cond-> errors - (str/empty? password) - (assoc :password {:message (tr "auth.password-not-empty")})))) - (s/def ::fullname ::us/not-empty-string) (s/def ::password ::us/not-empty-string) (s/def ::email ::us/email) @@ -95,7 +87,8 @@ [{:keys [params on-success-callback] :as props}] (let [initial (mf/use-memo (mf/deps params) (constantly params)) form (fm/use-form :spec ::register-form - :validators [validate validate-password] + :validators [validate + (fm/validate-not-empty :password (tr "auth.password-not-empty"))] :initial initial) submitted? (mf/use-state false) @@ -227,6 +220,8 @@ (mf/defc register-validate-form [{:keys [params on-success-callback] :as props}] (let [form (fm/use-form :spec ::register-validate-form + :validators [(fm/validate-not-empty :fullname (tr "auth.name.not-all-space")) + (fm/validate-length :fullname fm/max-length-allowed (tr "auth.name.too-long"))] :initial params) submitted? (mf/use-state false) diff --git a/frontend/src/app/main/ui/components/forms.cljs b/frontend/src/app/main/ui/components/forms.cljs index f8441061e..deb8f6a46 100644 --- a/frontend/src/app/main/ui/components/forms.cljs +++ b/frontend/src/app/main/ui/components/forms.cljs @@ -58,7 +58,7 @@ help-icon) on-change-value (or on-change-value (constantly nil)) - + klass (str more-classes " " (dom/classnames :focus @focus? @@ -138,7 +138,6 @@ (string? hint) [:span.hint hint])]])) - (mf/defc textarea [{:keys [label disabled form hint trim] :as props}] (let [input-name (get props :name) @@ -225,7 +224,7 @@ (for [item options] [:> :option (clj->js (cond-> {:key (:value item) :value (:value item)} (:disabled item) (assoc :disabled "disabled") - (:hidden item) (assoc :style {:display "none"}))) + (:hidden item) (assoc :style {:display "none"}))) (:label item)])] [:div.input-container {:class (dom/classnames :disabled disabled :focus @focus?)} @@ -240,7 +239,7 @@ [{:keys [name options form trim on-change-value] :as props}] (let [form (or form (mf/use-ctx form-ctx)) value (get-in @form [:data name] "") - on-change-value (or on-change-value (constantly nil)) + on-change-value (or on-change-value (constantly nil)) on-change (fn [event] (let [value (-> event dom/get-target dom/get-value)] (swap! form assoc-in [:touched name] true) @@ -412,3 +411,31 @@ "caution" (:caution item))} [:span.text (:text item)] [:span.icon {:on-click #(remove-item! item)} i/cross]]])])])) + +;; --- Validators + +(defn all-spaces? + [value] + (let [trimmed (str/trim value)] + (str/empty? trimmed))) + +(def max-length-allowed 250) +(def max-uri-length-allowed 2048) + +(defn max-length? + [value length] + (> (count value) length)) + +(defn validate-length + [field length errors-msg ] + (fn [errors data] + (cond-> errors + (max-length? (get data field) length) + (assoc field {:message errors-msg})))) + +(defn validate-not-empty + [field error-msg] + (fn [errors data] + (cond-> errors + (all-spaces? (get data field)) + (assoc field {:message error-msg})))) diff --git a/frontend/src/app/main/ui/dashboard/team.cljs b/frontend/src/app/main/ui/dashboard/team.cljs index dcd4ef867..f2a6625c4 100644 --- a/frontend/src/app/main/ui/dashboard/team.cljs +++ b/frontend/src/app/main/ui/dashboard/team.cljs @@ -658,7 +658,8 @@ (let [initial (mf/use-memo (fn [] (or (some-> webhook (update :uri str)) {:is-active false :mtype "application/json"}))) form (fm/use-form :spec ::webhook-form - :initial initial) + :initial initial + :validators [(fm/validate-length :uri fm/max-uri-length-allowed (tr "team.webhooks.max-length"))]) on-success (mf/use-fn (fn [_] @@ -750,8 +751,7 @@ [:& fm/input {:type "checkbox" :form form :name :is-active - :label (tr "dashboard.webhooks.active")}] - ] + :label (tr "dashboard.webhooks.active")}]] [:div.explain (tr "dashboard.webhooks.active.explain")]]] [:div.modal-footer diff --git a/frontend/src/app/main/ui/dashboard/team_form.cljs b/frontend/src/app/main/ui/dashboard/team_form.cljs index 81579044c..e09501b60 100644 --- a/frontend/src/app/main/ui/dashboard/team_form.cljs +++ b/frontend/src/app/main/ui/dashboard/team_form.cljs @@ -17,20 +17,12 @@ [app.util.router :as rt] [beicon.core :as rx] [cljs.spec.alpha :as s] - [cuerdas.core :as str] [rumext.v2 :as mf])) (s/def ::name ::us/not-empty-string) (s/def ::team-form (s/keys :req-un [::name])) -(defn- validate-name - [errors data] - (let [name (-> data :name str/trim)] - (cond-> errors - (str/empty? name) - (assoc :name {:message (tr "dashboard.team-name.not-empty-name")})))) - (defn- on-create-success [_form response] (let [msg "Team created successfully"] @@ -78,7 +70,8 @@ [{:keys [team] :as props}] (let [initial (mf/use-memo (fn [] (or team {}))) form (fm/use-form :spec ::team-form - :validators [validate-name] + :validators [(fm/validate-not-empty :name (tr "auth.name.not-all-space")) + (fm/validate-length :name fm/max-length-allowed (tr "auth.name.too-long"))] :initial initial)] [:div.modal-overlay [:div.modal-container.team-form-modal diff --git a/frontend/src/app/main/ui/onboarding/team_choice.cljs b/frontend/src/app/main/ui/onboarding/team_choice.cljs index f34fab29b..2dd7ee3de 100644 --- a/frontend/src/app/main/ui/onboarding/team_choice.cljs +++ b/frontend/src/app/main/ui/onboarding/team_choice.cljs @@ -54,7 +54,9 @@ ::mf/register-as :onboarding-team} [] (let [form (fm/use-form :spec ::team-form - :initial {}) + :initial {} + :validators [(fm/validate-not-empty :name (tr "auth.name.not-all-space")) + (fm/validate-length :name fm/max-length-allowed (tr "auth.name.too-long"))]) on-submit (mf/use-callback (fn [form _] diff --git a/frontend/src/app/main/ui/settings/access_tokens.cljs b/frontend/src/app/main/ui/settings/access_tokens.cljs index 66606b753..2444324ed 100644 --- a/frontend/src/app/main/ui/settings/access_tokens.cljs +++ b/frontend/src/app/main/ui/settings/access_tokens.cljs @@ -42,7 +42,6 @@ (str/blank? name) (assoc :name {:message (tr "dashboard.access-tokens.errors-required-name")})))) - (def initial-data {:name "" :expiration-date "never"}) @@ -53,7 +52,9 @@ (let [form (fm/use-form :initial initial-data :spec ::access-token-form - :validators [name-validator]) + :validators [name-validator + (fm/validate-not-empty :name (tr "auth.name.not-all-space")) + (fm/validate-length :name fm/max-length-allowed (tr "auth.name.too-long"))]) created (mf/deref token-created-ref) created? (mf/use-state false) locale (mf/deref i18n/locale) diff --git a/frontend/src/app/main/ui/settings/feedback.cljs b/frontend/src/app/main/ui/settings/feedback.cljs index fd3d9eedb..d510ef7c5 100644 --- a/frontend/src/app/main/ui/settings/feedback.cljs +++ b/frontend/src/app/main/ui/settings/feedback.cljs @@ -28,8 +28,9 @@ (mf/defc feedback-form [] (let [profile (mf/deref refs/profile) - form (fm/use-form :spec ::feedback-form) - + form (fm/use-form :spec ::feedback-form + :validators [(fm/validate-length :subject fm/max-length-allowed (tr "auth.name.too-long")) + (fm/validate-not-empty :subject (tr "auth.name.not-all-space"))]) loading (mf/use-state false) on-succes diff --git a/frontend/src/app/main/ui/settings/password.cljs b/frontend/src/app/main/ui/settings/password.cljs index f9ab2a915..48f15b00b 100644 --- a/frontend/src/app/main/ui/settings/password.cljs +++ b/frontend/src/app/main/ui/settings/password.cljs @@ -14,7 +14,6 @@ [app.util.dom :as dom] [app.util.i18n :as i18n :refer [t tr]] [cljs.spec.alpha :as s] - [cuerdas.core :as str] [rumext.v2 :as mf])) (defn- on-error @@ -63,17 +62,6 @@ (and password-1 (> 8 (count password-1))) (assoc :password-1 {:message (tr "errors.password-too-short")})))) -(defn- validate-password - [errors data] - (let [password-1 (-> data :password-1 str/trim) - password-2 (-> data :password-2 str/trim)] - (cond-> errors - (str/empty? password-1) - (assoc :password-1 {:message (tr "auth.password-not-empty")}) - - (str/empty? password-2) - (assoc :password-2 {:message (tr "auth.password-not-empty")})))) - (s/def ::password-form (s/keys :req-un [::password-1 ::password-2 @@ -83,7 +71,9 @@ [{:keys [locale] :as props}] (let [initial (mf/use-memo (constantly {:password-old nil})) form (fm/use-form :spec ::password-form - :validators [validate-password password-equality] + :validators [(fm/validate-not-empty :password-1 (tr "auth.password-not-empty")) + (fm/validate-not-empty :password-2 (tr "auth.password-not-empty")) + password-equality] :initial initial)] [:& fm/form {:class "password-form" :on-submit on-submit diff --git a/frontend/src/app/main/ui/settings/profile.cljs b/frontend/src/app/main/ui/settings/profile.cljs index 9a13dbaed..cbb302b70 100644 --- a/frontend/src/app/main/ui/settings/profile.cljs +++ b/frontend/src/app/main/ui/settings/profile.cljs @@ -42,7 +42,10 @@ (mf/defc profile-form [] (let [profile (mf/deref refs/profile) - form (fm/use-form :spec ::profile-form :initial profile)] + form (fm/use-form :spec ::profile-form + :initial profile + :validators [(fm/validate-length :fullname fm/max-length-allowed (tr "auth.name.too-long")) + (fm/validate-not-empty :fullname (tr "auth.name.not-all-space"))])] [:& fm/form {:on-submit on-submit :form form diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs index 0f8ff338f..82cbe41f9 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs @@ -134,6 +134,8 @@ (mf/deps last-path) (constantly {:asset-name last-path})) form (fm/use-form :spec ::name-group-form + :validators [(fm/validate-not-empty :name (tr "auth.name.not-all-space")) + (fm/validate-length :name fm/max-length-allowed (tr "auth.name.too-long"))] :initial initial) create? (empty? path) diff --git a/frontend/translations/en.po b/frontend/translations/en.po index d1c88fc3b..bfefc32b1 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -53,6 +53,14 @@ msgstr "Full Name" msgid "auth.login-here" msgstr "Login here" +#: src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs +msgid "auth.name.too-long" +msgstr "The name must contain at most 250 characters." + +#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs +msgid "auth.name.not-all-space" +msgstr "The name must contain some character other than space." + #: src/app/main/ui/auth/login.cljs msgid "auth.login-submit" msgstr "Login" @@ -375,10 +383,6 @@ msgstr "180 days" msgid "dashboard.access-tokens.errors-required-name" msgstr "The name is required" -#: src/app/main/ui/settings/team-form.cljs -msgid "dashboard.team-name.not-empty-name" -msgstr "The name must contain some character other than space." - #: src/app/main/ui/settings/access-tokens.cljs msgid "dashboard.access-tokens.token-will-expire" msgstr "The token will expire on %s" @@ -812,6 +816,10 @@ msgstr "No webhooks created so far." msgid "dashboard.webhooks.update.success" msgstr "Webhook updated successfully." +#: src/app/main/ui/dashboard/team.cljs +msgid "team.webhooks.max-length" +msgstr "The webhook name must contain at most 2048 characters." + #: src/app/main/ui/settings.cljs msgid "dashboard.your-account-title" msgstr "Your account" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 9cadae14d..dcdd6727b 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -56,6 +56,14 @@ msgstr "Nombre completo" msgid "auth.login-here" msgstr "Inicia sesión aquí" +#: src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs +msgid "auth.name.too-long" +msgstr "El nombre debe contener como máximo 250 caracteres." + +#: src/app/main/ui/settings/team-form.cljs, src/app/main/ui/auth/register.cljs, src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/onboarding/team_choice.cljs, src/app/main/ui/settings/access_tokens.cljs, src/app/main/ui/settings/feedback.cljs, src/app/main/ui/settings/profile.cljs, src/app/main/ui/workspace/sidebar/assets.cljs +msgid "auth.name.not-all-space" +msgstr "El nombre debe contener algún carácter diferente de espacio" + #: src/app/main/ui/auth/login.cljs msgid "auth.login-submit" msgstr "Entrar" @@ -382,10 +390,6 @@ msgstr "180 días" msgid "dashboard.access-tokens.errors-required-name" msgstr "El nombre es obligatorio" -#: src/app/main/ui/settings/team-form.cljs -msgid "dashboard.team-name.not-empty-name" -msgstr "El nombre debe contener algún carácter diferente de espacio" - #: src/app/main/ui/settings/access-tokens.cljs msgid "dashboard.access-tokens.token-will-expire" msgstr "El token expirará el %s" @@ -828,6 +832,10 @@ msgstr "No hay ningún webhook aún." msgid "dashboard.webhooks.update.success" msgstr "Webhook modificado con éxito." +#: src/app/main/ui/dashboard/team.cljs +msgid "team.webhooks.max-length" +msgstr "El nombre del webhook debe contener como máximo 2048 caracteres." + #: src/app/main/ui/settings.cljs msgid "dashboard.your-account-title" msgstr "Tu cuenta"