From fb0f230f64e2a98c5f99c871c775e8d5609ebe82 Mon Sep 17 00:00:00 2001 From: tischsoic Date: Tue, 18 Aug 2026 23:06:08 +0200 Subject: [PATCH 1/3] IBX-11959: Added password requirements info to Set new password screen Co-Authored-By: Claude --- src/bundle/Resources/public/scss/_login.scss | 5 ++ .../public/scss/_password-requirements.scss | 53 ++++++++++++ src/bundle/Resources/public/scss/ibexa.scss | 1 + .../Resources/translations/messages.en.xliff | 5 ++ .../account/reset_password/index.html.twig | 81 ++++++++++++++++++- 5 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 src/bundle/Resources/public/scss/_password-requirements.scss diff --git a/src/bundle/Resources/public/scss/_login.scss b/src/bundle/Resources/public/scss/_login.scss index 8147536a8..965e0bbbd 100644 --- a/src/bundle/Resources/public/scss/_login.scss +++ b/src/bundle/Resources/public/scss/_login.scss @@ -43,6 +43,10 @@ margin-top: calculateRem(16px); } + .ibexa-form-error__row { + margin-top: calculateRem(4px); + } + &__logo { max-width: calculateRem(250px); margin-bottom: calculateRem(32px); @@ -128,6 +132,7 @@ &__actions-headline { font-size: $text-font-size-3xl; + line-height: 1.2; margin-bottom: calculateRem(4px); } diff --git a/src/bundle/Resources/public/scss/_password-requirements.scss b/src/bundle/Resources/public/scss/_password-requirements.scss new file mode 100644 index 000000000..baae782b2 --- /dev/null +++ b/src/bundle/Resources/public/scss/_password-requirements.scss @@ -0,0 +1,53 @@ +@use '@ibexa-admin-ui/src/bundle/Resources/public/scss/custom.scss' as *; +@use '@ibexa-admin-ui/src/bundle/Resources/public/scss/functions/calculate.rem' as *; +@use '@ibexa-admin-ui-assets/src/bundle/Resources/public/vendors/ids-assets/dist/scss/variables/colors' as *; +@use '@ibexa-admin-ui-assets/src/bundle/Resources/public/vendors/ids-assets/dist/scss/variables/typography' as *; + +.ibexa-password-requirements { + &__intro { + margin-bottom: 0; + font-size: $text-font-size-m; + color: $color-neutral-160; + } + + &__list { + list-style: none; + margin: 0; + padding: 0; + } + + &__item { + position: relative; + padding-left: calculateRem(20px); + font-size: $text-font-size-m; + color: $color-neutral-160; + + &::before { + content: ''; + position: absolute; + top: 50%; + left: calculateRem(6px); + width: calculateRem(4px); + height: calculateRem(4px); + border-radius: 50%; + background-color: $color-neutral-160; + transform: translateY(-50%); + } + + &--met { + color: $ibexa-color-success-600; + + &::before { + display: none; + } + } + } + + &__item-icon { + position: absolute; + top: 50%; + left: calculateRem(2px); + fill: $ibexa-color-success-600; + transform: translateY(-50%); + } +} diff --git a/src/bundle/Resources/public/scss/ibexa.scss b/src/bundle/Resources/public/scss/ibexa.scss index 73dbe3c9d..62d8b68cf 100644 --- a/src/bundle/Resources/public/scss/ibexa.scss +++ b/src/bundle/Resources/public/scss/ibexa.scss @@ -21,6 +21,7 @@ @use 'notifications'; @use 'instant-filter'; @use 'login'; +@use 'password-requirements'; @use 'forms'; @use 'preview-header'; @use 'preview'; diff --git a/src/bundle/Resources/translations/messages.en.xliff b/src/bundle/Resources/translations/messages.en.xliff index 9db925d9e..bc9b55d35 100644 --- a/src/bundle/Resources/translations/messages.en.xliff +++ b/src/bundle/Resources/translations/messages.en.xliff @@ -311,6 +311,11 @@ generate a new link to reset your password.]]> key: ezplatform.reset_user_password.link_is_not_valid + + To keep your account secure, your password must meet the following requirements: + To keep your account secure, your password must meet the following requirements: + key: ezplatform.reset_user_password.requirements_intro + log in to Cohesivo.]]> log in to Cohesivo.]]> diff --git a/src/bundle/Resources/views/themes/admin/account/reset_password/index.html.twig b/src/bundle/Resources/views/themes/admin/account/reset_password/index.html.twig index 034f635ff..2cc3451a2 100644 --- a/src/bundle/Resources/views/themes/admin/account/reset_password/index.html.twig +++ b/src/bundle/Resources/views/themes/admin/account/reset_password/index.html.twig @@ -4,12 +4,89 @@ {% form_theme form_reset_user_password '@ibexadesign/ui/form_fields.html.twig' %} {% endif %} +{% macro password_field_errors(errors) %} +
+ {% for error in errors %} + + + + + {{ error.message }} + + {% endfor %} +
+{% endmacro %} + {%- block content -%} + {% import _self as reset_password_macros %} + {% if form_reset_user_password is defined %} + {% set new_password_form = form_reset_user_password.new_password %} + {% set requirements = content_type is defined ? ibexa_password_requirements(content_type) : [] %} + {% set requirement_identifiers = requirements|map((requirement) => requirement.identifier) %} + + {# RepeatedType maps its errors to the first child; the compound is read too, defensively #} + {% set password_errors = [] %} + {% for error in new_password_form.vars.errors %} + {% set password_errors = password_errors|merge([error]) %} + {% endfor %} + {% for error in new_password_form.first.vars.errors %} + {% set password_errors = password_errors|merge([error]) %} + {% endfor %} + + {% set policy_errors = password_errors|filter((error) => error.cause.code|default(null) in requirement_identifiers) %} + {% set other_errors = password_errors|filter((error) => error.cause.code|default(null) not in requirement_identifiers) %} + {% set failed_requirement_identifiers = policy_errors|map((error) => error.cause.code) %} + {# on any non-policy error (e.g. passwords mismatch) the Password constraint did not run, so met/unmet is unknown #} + {% set can_mark_requirements = form_reset_user_password.vars.submitted and other_errors is empty %} + + {% if requirements is not empty %} +
+

+ {{ 'ezplatform.reset_user_password.requirements_intro'|trans|desc('To keep your account secure, your password must meet the following requirements:') }} +

+
    + {% for requirement in requirements %} + {% set is_met = can_mark_requirements and requirement.identifier not in failed_requirement_identifiers %} +
  • + {% if is_met %} + + + + {% endif %} + {{ requirement.translationKey|trans(requirement.parameters, 'ibexa_password_requirements') }} +
  • + {% endfor %} +
+
+ {% endif %} + {{ form_start(form_reset_user_password, {'attr': {'class': 'ibexa-form-validate'} }) }}
- {{ form_widget(form_reset_user_password.new_password) }} +
+ {{ form_label(new_password_form.first) }} + {{ form_widget(new_password_form.first, policy_errors is not empty + ? { attr: { class: 'is-invalid', error: true } } + : {} + ) }} + {% if policy_errors is not empty %} + {{ reset_password_macros.password_field_errors(policy_errors) }} + {% endif %} +
+
+ {{ form_label(new_password_form.second) }} + {{ form_widget(new_password_form.second, other_errors is not empty + ? { attr: { class: 'is-invalid', error: true } } + : {} + ) }} + {% if other_errors is not empty %} + {{ reset_password_macros.password_field_errors(other_errors) }} + {% endif %} +
{{ form_widget(form_reset_user_password.update, {'attr': {'class': 'ids-btn ids-btn--primary ids-btn--medium ibexa-login__btn ibexa-login__btn--change-password'}}) }} {{ form_end(form_reset_user_password) }} @@ -22,6 +99,6 @@ > {{ 'authentication.reset_your_password.back_to_sign_in'|trans|desc('Back to sign in page') }} - + {{ encore_entry_script_tags('ibexa-admin-ui-reset-password-js', null, 'ibexa') }} {%- endblock content -%} From 34b6f7a3db82689ca3271c85fa40e9fbbd22c03d Mon Sep 17 00:00:00 2001 From: tischsoic Date: Thu, 20 Aug 2026 12:39:47 +0200 Subject: [PATCH 2/3] IBX-11959: Removed explanatory comments from the password requirements template Co-Authored-By: Claude --- .../views/themes/admin/account/reset_password/index.html.twig | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/bundle/Resources/views/themes/admin/account/reset_password/index.html.twig b/src/bundle/Resources/views/themes/admin/account/reset_password/index.html.twig index 2cc3451a2..49acba07e 100644 --- a/src/bundle/Resources/views/themes/admin/account/reset_password/index.html.twig +++ b/src/bundle/Resources/views/themes/admin/account/reset_password/index.html.twig @@ -26,7 +26,6 @@ {% set requirements = content_type is defined ? ibexa_password_requirements(content_type) : [] %} {% set requirement_identifiers = requirements|map((requirement) => requirement.identifier) %} - {# RepeatedType maps its errors to the first child; the compound is read too, defensively #} {% set password_errors = [] %} {% for error in new_password_form.vars.errors %} {% set password_errors = password_errors|merge([error]) %} @@ -38,7 +37,6 @@ {% set policy_errors = password_errors|filter((error) => error.cause.code|default(null) in requirement_identifiers) %} {% set other_errors = password_errors|filter((error) => error.cause.code|default(null) not in requirement_identifiers) %} {% set failed_requirement_identifiers = policy_errors|map((error) => error.cause.code) %} - {# on any non-policy error (e.g. passwords mismatch) the Password constraint did not run, so met/unmet is unknown #} {% set can_mark_requirements = form_reset_user_password.vars.submitted and other_errors is empty %} {% if requirements is not empty %} From e92078b1c1620d2379bb6a0428526b3a5966e724 Mon Sep 17 00:00:00 2001 From: tischsoic Date: Thu, 20 Aug 2026 12:50:03 +0200 Subject: [PATCH 3/3] IBX-11959: Applied the form error row spacing globally Co-Authored-By: Claude --- src/bundle/Resources/public/scss/_forms.scss | 2 +- src/bundle/Resources/public/scss/_login.scss | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/bundle/Resources/public/scss/_forms.scss b/src/bundle/Resources/public/scss/_forms.scss index 76d166cca..026f98a09 100644 --- a/src/bundle/Resources/public/scss/_forms.scss +++ b/src/bundle/Resources/public/scss/_forms.scss @@ -99,7 +99,7 @@ form:not(.form-inline) { display: flex; align-items: center; font-style: normal; - margin-top: calculateRem(8px); + margin-top: calculateRem(4px); } &__icon { diff --git a/src/bundle/Resources/public/scss/_login.scss b/src/bundle/Resources/public/scss/_login.scss index 965e0bbbd..5f7b2a637 100644 --- a/src/bundle/Resources/public/scss/_login.scss +++ b/src/bundle/Resources/public/scss/_login.scss @@ -43,10 +43,6 @@ margin-top: calculateRem(16px); } - .ibexa-form-error__row { - margin-top: calculateRem(4px); - } - &__logo { max-width: calculateRem(250px); margin-bottom: calculateRem(32px);