Add password validation to update-password (#35479)

Closes #35478

Signed-off-by: SebastEnn <103125747+SebastEnn@users.noreply.github.com>
This commit is contained in:
SebastEnn 2024-12-03 14:33:21 +01:00 committed by GitHub
parent 4ad4a8d37b
commit 364572046f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 58 additions and 47 deletions

View File

@ -2,6 +2,7 @@
<#import "password-commons.ftl" as passwordCommons>
<#import "field.ftl" as field>
<#import "buttons.ftl" as buttons>
<#import "password-validation.ftl" as validator>
<@layout.registrationLayout displayMessage=!messagesPerField.existsError('password','password-confirm'); section>
<!-- template: login-update-password.ftl -->
<#if section = "header">
@ -24,5 +25,8 @@
</#if>
</@buttons.actionGroup>
</form>
<@validator.templates/>
<@validator.script field="password-new"/>
</#if>
</@layout.registrationLayout>

View File

@ -0,0 +1,51 @@
<#macro templates>
<template id="errorTemplate">
<div class="${properties.kcFormHelperTextClass}" aria-live="polite">
<div class="${properties.kcInputHelperTextClass}">
<div class="${properties.kcInputHelperTextItemClass} ${properties.kcError}">
<ul class="${properties.kcInputErrorMessageClass}">
</ul>
</div>
</div>
</div>
</template>
<template id="errorItemTemplate">
<li></li>
</template>
</#macro>
<#macro script field="">
<script type="module">
import { validatePassword } from "${url.resourcesPath}/js/password-policy.js";
const activePolicies = [
{ name: "length", policy: { value: ${passwordPolicies.length!-1}, error: "${msg('invalidPasswordMinLengthMessage')}"} },
{ name: "maxLength", policy: { value: ${passwordPolicies.maxLength!-1}, error: "${msg('invalidPasswordMaxLengthMessage')}"} },
{ name: "lowerCase", policy: { value: ${passwordPolicies.lowerCase!-1}, error: "${msg('invalidPasswordMinLowerCaseCharsMessage')}"} },
{ name: "upperCase", policy: { value: ${passwordPolicies.upperCase!-1}, error: "${msg('invalidPasswordMinUpperCaseCharsMessage')}"} },
{ name: "digits", policy: { value: ${passwordPolicies.digits!-1}, error: "${msg('invalidPasswordMinDigitsMessage')}"} },
{ name: "specialChars", policy: { value: ${passwordPolicies.specialChars!-1}, error: "${msg('invalidPasswordMinSpecialCharsMessage')}"} }
].filter(p => p.policy.value !== -1);
document.getElementById("${field}").addEventListener("change", (event) => {
const errorContainer = document.getElementById("input-error-container-${field}");
const template = document.querySelector("#errorTemplate").content.cloneNode(true);
const errors = validatePassword(event.target.value, activePolicies);
if (errors.length === 0) {
errorContainer.replaceChildren();
return;
}
const errorList = template.querySelector("ul");
const htmlErrors = errors.forEach((e) => {
const row = document.querySelector("#errorItemTemplate").content.cloneNode(true);
const li = row.querySelector("li");
li.textContent = e;
errorList.appendChild(li);
});
errorContainer.replaceChildren(template);
});
</script>
</#macro>

View File

@ -2,6 +2,7 @@
<#import "field.ftl" as field>
<#import "user-profile-commons.ftl" as userProfileCommons>
<#import "register-commons.ftl" as registerCommons>
<#import "password-validation.ftl" as validator>
<@layout.registrationLayout displayMessage=messagesPerField.exists('global') displayRequiredFields=true; section>
<!-- template: register.ftl -->
@ -61,52 +62,7 @@
</form>
<template id="errorTemplate">
<div class="${properties.kcFormHelperTextClass}" aria-live="polite">
<div class="${properties.kcInputHelperTextClass}">
<div class="${properties.kcInputHelperTextItemClass} ${properties.kcError}">
<ul class="${properties.kcInputErrorMessageClass}">
</ul>
</div>
</div>
</div>
</template>
<template id="errorItemTemplate">
<li></li>
</template>
<script type="module">
import { validatePassword } from "${url.resourcesPath}/js/password-policy.js";
const activePolicies = [
{ name: "length", policy: { value: ${passwordPolicies.length!-1}, error: "${msg('invalidPasswordMinLengthMessage')}"} },
{ name: "maxLength", policy: { value: ${passwordPolicies.maxLength!-1}, error: "${msg('invalidPasswordMaxLengthMessage')}"} },
{ name: "lowerCase", policy: { value: ${passwordPolicies.lowerCase!-1}, error: "${msg('invalidPasswordMinLowerCaseCharsMessage')}"} },
{ name: "upperCase", policy: { value: ${passwordPolicies.upperCase!-1}, error: "${msg('invalidPasswordMinUpperCaseCharsMessage')}"} },
{ name: "digits", policy: { value: ${passwordPolicies.digits!-1}, error: "${msg('invalidPasswordMinDigitsMessage')}"} },
{ name: "specialChars", policy: { value: ${passwordPolicies.specialChars!-1}, error: "${msg('invalidPasswordMinSpecialCharsMessage')}"} }
].filter(p => p.policy.value !== -1);
document.getElementById("password").addEventListener("change", (event) => {
const errorContainer = document.getElementById("input-error-container-password");
const template = document.querySelector("#errorTemplate").content.cloneNode(true);
const errors = validatePassword(event.target.value, activePolicies);
if (errors.length === 0) {
errorContainer.replaceChildren();
return;
}
const errorList = template.querySelector("ul");
const htmlErrors = errors.forEach((e) => {
const row = document.querySelector("#errorItemTemplate").content.cloneNode(true);
const li = row.querySelector("li");
li.textContent = e;
errorList.appendChild(li);
});
errorContainer.replaceChildren(template);
});
</script>
<@validator.templates/>
<@validator.script field="password"/>
</#if>
</@layout.registrationLayout>