diff --git a/themes/src/main/resources/theme/keycloak.v2/login/field.ftl b/themes/src/main/resources/theme/keycloak.v2/login/field.ftl index 538f387052..845f5994f3 100644 --- a/themes/src/main/resources/theme/keycloak.v2/login/field.ftl +++ b/themes/src/main/resources/theme/keycloak.v2/login/field.ftl @@ -14,6 +14,7 @@ <#nested> +
<#if error?has_content>
diff --git a/themes/src/main/resources/theme/keycloak.v2/login/register.ftl b/themes/src/main/resources/theme/keycloak.v2/login/register.ftl index 726b4ffea7..0e06d693aa 100755 --- a/themes/src/main/resources/theme/keycloak.v2/login/register.ftl +++ b/themes/src/main/resources/theme/keycloak.v2/login/register.ftl @@ -13,7 +13,6 @@ <#elseif section = "form">
- <@userProfileCommons.userProfileFormFields; callback, attribute> <#if callback = "afterField"> <#-- render password fields just under the username or email (if used as username) --> @@ -46,5 +45,50 @@
+ + + + + diff --git a/themes/src/main/resources/theme/keycloak.v2/login/resources/js/password-policy.js b/themes/src/main/resources/theme/keycloak.v2/login/resources/js/password-policy.js new file mode 100644 index 0000000000..466bcc6636 --- /dev/null +++ b/themes/src/main/resources/theme/keycloak.v2/login/resources/js/password-policy.js @@ -0,0 +1,53 @@ +const policies = { + length: (policy, value) => { + if (value.length < policy.value) { + return templateError(policy); + } + }, + maxLength: (policy, value) => { + if (value.length > policy.value) { + return templateError(policy); + } + }, + upperCase: (policy, value) => { + if ( + value.split("").filter((char) => char !== char.toUpperCase()).length > + policy.value + ) { + return templateError(policy); + } + }, + lowerCase: (policy, value) => { + if ( + value.split("").filter((char) => char !== char.toLowerCase()).length > + policy.value + ) { + return templateError(policy); + } + }, + digits: (policy, value) => { + const digits = value.split("").filter((char) => char.match(/\d/)); + if (digits.length < policy.value) { + return templateError(policy); + } + }, + specialChars: (policy, value) => { + let specialChars = value.split("").filter((char) => char.match(/\W/)); + if (specialChars.length < policy.value) { + return templateError(policy); + } + }, +}; + +const templateError = (policy) => policy.error.replace("{0}", policy.value); + +export function validatePassword(password, activePolicies) { + const errors = []; + for (const p of activePolicies) { + const validationError = policies[p.name](p.policy, password); + if (validationError) { + errors.push(validationError); + } + } + return errors; +}