I am trying to increase the security of my website and user account settings. So I wanted to insert a password strength meter to give the password a security level. Everything works correctly but it seems to be just a question of style.
When you change your password, even if you do not respect the rules imposed in the strength meter you are still allowed to wash the password and the settings are successful.
So how can I prevent this? I wish the settings would not be saved if you don't respect the strength meter, otherwise it makes no sense.
I'm working with wordpress, but the form account setting belongs to woocommerce. Can some Good Samaritan help me understand what I'm doing wrong? I appreciate any help, thanks.
/* Show Hide Password */
function showPassword(targetID) {
var pw = document.getElementById(targetID);
if (pw.type === "password") {
pw.type = "text";
} else {
pw.type = "password";
}
}
/*Add class Active to Modifica password*/
document.getElementById('editpw').onclick = function() {
this.classList.toggle('actived');
}
/* Dropdown Password Field */
var dropdownBtn = document.querySelectorAll('.drop_btn');
iconDrop = null;
lastOpened = null; //Add this for toggling dropdown
dropdownBtn.forEach(btn => btn.addEventListener('click', function() {
var dropCont = this.nextElementSibling;
let icon = this.querySelector('.icon_item');
icon.classList.toggle("down");
dropCont.classList.toggle("show");
//Add this for toggling dropdown
if (lastOpened && lastOpened !== dropCont)
lastOpened.classList.remove("show");
lastOpened = dropCont;
if (iconDrop && iconDrop !== icon)
iconDrop.classList.remove("down");
iconDrop = icon;
}));
/*Start Password Strength Meter*/
var myInput = document.getElementById("password_1");
var letter = document.getElementById("letter");
var capital = document.getElementById("capital");
var number = document.getElementById("number");
var length = document.getElementById("length");
// When the user clicks on the password field, show the message box
myInput.onfocus = function() {
document.getElementById("message").style.display = "block";
}
// When the user clicks outside of the password field, hide the message box
myInput.onblur = function() {
document.getElementById("message").style.display = "none";
}
// When the user starts to type something inside the password field
myInput.onkeyup = function() {
// Validate lowercase letters
var lowerCaseLetters = /[a-z]/g;
if(myInput.value.match(lowerCaseLetters)) {
letter.classList.remove("invalid");
letter.classList.add("valid");
} else {
letter.classList.remove("valid");
letter.classList.add("invalid");
}
// Validate capital letters
var upperCaseLetters = /[A-Z]/g;
if(myInput.value.match(upperCaseLetters)) {
capital.classList.remove("invalid");
capital.classList.add("valid");
} else {
capital.classList.remove("valid");
capital.classList.add("invalid");
}
// Validate numbers
var numbers = /[0-9]/g;
if(myInput.value.match(numbers)) {
number.classList.remove("invalid");
number.classList.add("valid");
} else {
number.classList.remove("valid");
number.classList.add("invalid");
}
// Validate length
if(myInput.value.length >= 8) {
length.classList.remove("invalid");
length.classList.add("valid");
} else {
length.classList.remove("valid");
length.classList.add("invalid");
}
}
/*Form Style*/
.form-container {
display: flex;
flex-direction: column;
padding: 20px;
border-radius: 6px;
box-shadow: rgb(0 0 0 / 15%) 0px 5px 15px -5px;
border: 1px solid var(--e-global-color-2075d85);
}
.box-name-surname {
display: flex; gap: 20px;
}
.form-row {
width: 100%; margin-bottom: 18px!important;
}
.edit-account-button { height: 30px; font-size: 14px; font-weight: 400; }
fieldset {
border: 0!important; margin: 0!important; padding: 5px!important;
}
/*Input fields*/
input.field-settings {
width: 100%;
border-radius: 4px!important;
border: 2px solid #efefef!important;
padding: 12px!important;
margin-bottom: 6px;
height: 15px;
}
input.field-settings:focus {
border: 2px solid #6FA4F2!important;
}
input.field-settings.disabled {
background: var(--e-global-color-2606bfd);
color: var(--e-global-color-43596cc);
}
label.t2 {
font-size: 14px!important;
line-height: 1.5em!important;
font-weight: 500!important;
margin-bottom: 6px!important;
display: block;
}
span.t4-light {
margin: 0 6px;
display: block;
font-style: italic;
}
/*Toggle Password*/
.togglePw { display: none; margin-bottom: 0;}
.togglePw label:before {
content: "\f06e";
font: var(--fa-font-solid);
margin-bottom: 6px;
margin-left: -30px;
display: block;
color: #8C9099;
}
.togglePw:checked label:before {
content: "\f070";
font: var(--fa-font-solid);
margin-bottom: 6px;
margin-left: -30px;
display: block;
color: #1E70EB;
}
.input-group { display: flex; align-items: center; }
/*Dropdown Function Style*/
.drop_btn {
display: flex;
align-items: center;
padding: 10px;
margin-bottom: 24px;
border-bottom: 1px solid #efefef;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: 0.2s all;
}
.drop_btn:hover {
color: #1E70EB;
}
.drop_btn.actived {
color: #1E70EB;
}
.icon_item {
font-family: fontAwesome;
content: '\f078';
display: inline-block;
position: absolute;
right: 2em;
margin: 0;
padding: 0;
transform: rotateY(0);
transform-origin: center;
transition: 0.1s linear;
}
.icon_item.down {
font-family: fontAwesome;
content: '\f325';
display: inline-block;
position: absolute;
right: 2em;
margin: 0;
padding: 0;
transform: rotateZ(180deg);
transform-origin: center;
transition: 0.1s linear;
}
.drop_container {
overflow: hidden;
max-height: 0;
transition: max-height 0.2s ease-out;
}
.drop_container.show {
max-height: 900px;
transition: max-height 0.3s ease-in;
}
.drop_container>.item {
display: flex;
flex-direction: column;
margin-left: 10px;
padding: 10px 0px 0px 0px;
}
/*Pasword Strength Meter*/
/* The message box is shown when the user clicks on the password field */
#message {
display:none;
background: #f1f1f1;
color: #000;
position: relative;
padding: 20px;
margin-top: 10px;
}
#message p {
padding: 10px 35px;
font-size: 18px;
}
/* Add a green text color and a checkmark when the requirements are right */
.valid {
color: green;
}
.valid:before {
position: relative;
left: -35px;
content: "✔";
}
/* Add a red text color and an "x" when the requirements are wrong */
.invalid {
color: red;
}
.invalid:before {
position: relative;
left: -35px;
content: "✖";
}
<?php
defined( 'ABSPATH' ) || exit;
do_action( 'woocommerce_before_edit_account_form' ); ?>
<form action="" method="post" <?php do_action( 'woocommerce_edit_account_form_tag' );?> >
<?php do_action( 'woocommerce_edit_account_form_start' ); ?>
<div >
<p >
<label for="account_first_name">First Name<span >*</span></label>
<input type="text" name="account_first_name" id="account_first_name" autocomplete="given-name" value="John" />
</p>
<p >
<label for="account_last_name">Last Name<span >*</span></label>
<input type="text" name="account_last_name" id="account_last_name" autocomplete="family-name" value="Doe" />
</p>
</div>
<div ></div>
<p >
<label for="account_user_login">Username</label>
<input type="text" name="account_user_login" id="account_user_login" disabled value="JohnDoeUser" />
</p>
<p >
<label for="account_display_name">Display Name<span >*</span></label>
<input type="text" name="account_display_name" id="account_display_name" value="John Doe" />
</p>
<div ></div>
<p >
<label for="account_email">Email<span >*</span></label>
<input type="email" name="account_email" id="account_email" autocomplete="email" value="[email protected]" />
</p>
<!-- Password Section -->
<div id="editpw" >Edit Password<i ></i></div>
<div >
<fieldset>
<p >
<label for="password_current">Current Password (leave blank to leave unchanged)</label>
<div >
<input type="password" name="password_current" id="password_current" autocomplete="off"/>
<input type="checkbox" id="pw_current" onclick="showPassword('password_current')"/>
<label for="pw_current" ></label>
</div>
</p>
<p >
<label for="password_1">New Password (leave blank to leave unchanged)</label>
<div >
<input type="password" name="password_1" id="password_1" autocomplete="off" />
<input type="checkbox" id="pw_1" onclick="showPassword('password_1')"/>
<label for="pw_1" ></label>
</div>
</p>
<p >
<label for="password_2">Confirm Password</label>
<div >
<input type="password" name="password_2" id="password_2" autocomplete="off" />
<input type="checkbox" id="pw_2" onclick="showPassword('password_2')"/>
<label for="pw_2" ></label>
</div>
</p>
</fieldset>
<div id="message">
<h3>Password must contain the following:</h3>
<p id="letter" >A <b>lowercase</b> letter</p>
<p id="capital" >A <b>capital (uppercase)</b> letter</p>
<p id="number" >A <b>number</b></p>
<p id="length" >Minimum <b>8 characters</b></p>
</div>
</div>
<div ></div>
<?php do_action( 'woocommerce_edit_account_form' ); ?>
<p>
<?php wp_nonce_field( 'save_account_details', 'save-account-details-nonce' ); ?>
<button type="submit" name="save_account_details" value="<?php esc_attr_e( 'Save changes', 'woocommerce' ); ?>">Save Changes</button>
<input type="hidden" name="action" value="save_account_details" />
</p>
<?php do_action( 'woocommerce_edit_account_form_end' ); ?>
</form>
<?php do_action( 'woocommerce_after_edit_account_form' ); ?>
CodePudding user response:
After a few days of looking for a solution I found one. I realized woocommerce provides its own password strength meter, but I didn't know it was there. Since it's already there I've used that.
/* Show Hide Password */
function showPassword(targetID) {
var pw = document.getElementById(targetID);
if (pw.type === "password") {
pw.type = "text";
} else {
pw.type = "password";
}
}
/*Add class Active to Modifica password*/
document.getElementById('editpw').onclick = function() {
this.classList.toggle('actived');
}
/* Dropdown Password Field */
var dropdownBtn = document.querySelectorAll('.drop_btn');
iconDrop = null;
lastOpened = null; //Add this for toggling dropdown
dropdownBtn.forEach(btn => btn.addEventListener('click', function() {
var dropCont = this.nextElementSibling;
let icon = this.querySelector('.icon_item');
icon.classList.toggle("down");
dropCont.classList.toggle("show");
//Add this for toggling dropdown
if (lastOpened && lastOpened !== dropCont)
lastOpened.classList.remove("show");
lastOpened = dropCont;
if (iconDrop && iconDrop !== icon)
iconDrop.classList.remove("down");
iconDrop = icon;
}));
// Start Strength Meter Password
/* global wp, pwsL10n, wc_password_strength_meter_params */
( function( $ ) {
'use strict';
/**
* Password Strength Meter class.
*/
var wc_password_strength_meter = {
/**
* Initialize strength meter actions.
*/
init: function() {
$( document.body )
.on(
'keyup change',
'form.register #reg_password, form.checkout #account_password, '
'form.mts-edit-account #password_1, form.lost_reset_password #password_1',
this.strengthMeter
);
$( 'form.checkout #createaccount' ).trigger( 'change' );
},
/**
* Strength Meter.
*/
strengthMeter: function() {
var wrapper = $( 'form.register, form.checkout, form.mts-edit-account, form.lost_reset_password' ),
submit = $( 'button[type="submit"]', wrapper ),
field = $( '#reg_password, #account_password, #password_1', wrapper ),
strength = 1,
fieldValue = field.val(),
stop_checkout = ! wrapper.is( 'form.checkout' ); // By default is disabled on checkout.
wc_password_strength_meter.includeMeter( wrapper, field );
strength = wc_password_strength_meter.checkPasswordStrength( wrapper, field );
// Allow password strength meter stop checkout.
if ( wc_password_strength_meter_params.stop_checkout ) {
stop_checkout = true;
}
if (
fieldValue.length > 0 &&
strength < wc_password_strength_meter_params.min_password_strength &&
-1 !== strength &&
stop_checkout
) {
submit.attr( 'disabled', 'disabled' ).addClass( 'disabled' );
} else {
submit.prop( 'disabled', false ).removeClass( 'disabled' );
}
},
/**
* Include meter HTML.
*
* @param {Object} wrapper
* @param {Object} field
*/
includeMeter: function( wrapper, field ) {
var meter = wrapper.find( '.woocommerce-password-strength' );
if ( '' === field.val() ) {
meter.hide();
$( document.body ).trigger( 'wc-password-strength-hide' );
} else if ( 0 === meter.length ) {
field.after( '<div aria-live="polite"></div>' );
$( document.body ).trigger( 'wc-password-strength-added' );
} else {
meter.show();
$( document.body ).trigger( 'wc-password-strength-show' );
}
},
/**
* Check password strength.
*
* @param {Object} field
*
* @return {Int}
*/
checkPasswordStrength: function( wrapper, field ) {
var meter = wrapper.find( '.woocommerce-password-strength' ),
hint = wrapper.find( '.woocommerce-password-hint' ),
hint_html = '<small >' wc_password_strength_meter_params.i18n_password_hint '</small>',
strength = wp.passwordStrength.meter( field.val(), wp.passwordStrength.userInputDisallowedList() ),
error = '';
// Reset.
meter.removeClass( 'short bad good strong' );
hint.remove();
if ( meter.is( ':hidden' ) ) {
return strength;
}
// Error to append
if ( strength < wc_password_strength_meter_params.min_password_strength ) {
error = ' - ' wc_password_strength_meter_params.i18n_password_error;
}
switch ( strength ) {
case 0 :
meter.addClass( 'short' ).html( pwsL10n['short'] error );
meter.after( hint_html );
break;
case 1 :
meter.addClass( 'bad' ).html( pwsL10n.bad error );
meter.after( hint_html );
break;
case 2 :
meter.addClass( 'bad' ).html( pwsL10n.bad error );
meter.after( hint_html );
break;
case 3 :
meter.addClass( 'good' ).html( pwsL10n.good error );
break;
case 4 :
meter.addClass( 'strong' ).html( pwsL10n.strong error );
break;
case 5 :
meter.addClass( 'short' ).html( pwsL10n.mismatch );
break;
}
return strength;
}
};
wc_password_strength_meter.init();
})( jQuery );
/*Form Style*/
.mts-edit-account {
display: flex;
flex-direction: column;
padding: 20px;
border-radius: 6px;
box-shadow: rgb(0 0 0 / 15%) 0px 5px 15px -5px;
border: 1px solid var(--e-global-color-2075d85);
}
.box-name-surname {
display: flex; gap: 20px;
}
.form-row {
width: 100%; margin-bottom: 18px!important;
}
.edit-account-button { height: 30px; font-size: 14px; font-weight: 400; }
.edit-account-button.disabled { background-color: #8C9099; }
.edit-account-button.disabled:hover { background-color: #8C9099; }
fieldset {
border: 0!important; margin: 0!important; padding: 5px!important;
}
/*Input fields*/
input.field-settings {
width: 100%;
border-radius: 4px!important;
border: 2px solid #efefef!important;
padding: 12px!important;
margin-bottom: 6px;
height: 20px;
}
input.field-settings:focus {
border: 2px solid #6FA4F2!important;
}
input.field-settings.disabled {
background: var(--e-global-color-2606bfd);
color: var(--e-global-color-43596cc);
}
label.t2 {
font-size: 14px!important;
line-height: 1.5em!important;
font-weight: 500!important;
margin-bottom: 6px!important;
display: block;
}
span.t4-light {
margin: 0 6px;
display: block;
}
/*Toggle Password*/
.togglePw { display: none; margin-bottom: 0;}
.togglePw label:before {
content: "\f06e";
font: var(--fa-font-solid);
margin-bottom: 6px;
margin-left: -30px;
display: block;
color: #8C9099;
}
.togglePw:checked label:before {
content: "\f070";
font: var(--fa-font-solid);
margin-bottom: 6px;
margin-left: -30px;
display: block;
color: #1E70EB;
}
.input-group { display: flex; align-items: center; }
/*Dropdown Function Style*/
.drop_btn {
display: flex;
align-items: center;
padding: 10px;
margin-bottom: 24px;
border-bottom: 1px solid #efefef;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: 0.2s all;
}
.drop_btn:hover {
color: #1E70EB;
}
.drop_btn.actived {
color: #1E70EB;
}
.icon_item {
font-family: fontAwesome;
content: '\f078';
display: inline-block;
position: absolute;
right: 2em;
margin: 0;
padding: 0;
transform: rotateY(0);
transform-origin: center;
transition: 0.1s linear;
}
.icon_item.down {
font-family: fontAwesome;
content: '\f325';
display: inline-block;
position: absolute;
right: 2em;
margin: 0;
padding: 0;
transform: rotateZ(180deg);
transform-origin: center;
transition: 0.1s linear;
}
.drop_container {
overflow: hidden;
max-height: 0;
transition: max-height 0.2s ease-out;
}
.drop_container.show {
max-height: 900px;
transition: max-height 0.3s ease-in;
}
.drop_container>.item {
display: flex;
flex-direction: column;
margin-left: 10px;
padding: 10px 0px 0px 0px;
}
/*Pasword Strength Meter*/
/* The message box is shown when the user clicks on the password field */
#message {
display:none;
background: #f1f1f1;
color: #000;
position: relative;
padding: 20px;
margin-top: 10px;
}
#message p {
padding: 10px 35px;
font-size: 18px;
}
/* Add a green text color and a checkmark when the requirements are right */
.valid {
color: green;
}
.valid:before {
position: relative;
left: -35px;
content: "✔";
}
/* Add a red text color and an "x" when the requirements are wrong */
.invalid {
color: red;
}
.invalid:before {
position: relative;
left: -35px;
content: "✖";
}
/*Woocommerce Password Strength Meter*/
.woocommerce-password-strength.short {
background-color: #ffffff00;
border-color: #ffffff00;
text-align: right;
color: #E11536;
padding: 5px;
}
.woocommerce-password-strength.short:after {
font-family: fontAwesome;
font: var(--fa-font-solid);
content: '\e368';
font-size: 18px;
margin-left: 10px;
}
.woocommerce-password-strength.bad {
background-color: #ffffff00;
border-color: #ffffff00;
text-align: right;
color: #EA580C;
padding: 5px;
}
.woocommerce-password-strength.bad:after {
font-family: fontAwesome;
font: var(--fa-font-solid);
content: '\e36f';
font-size: 18px;
margin-left: 10px;
}
.woocommerce-password-strength.good {
background-color: #ffffff00;
border-color: #ffffff00;
text-align: right;
color: #1E70EB;
padding: 5px;
}
.woocommerce-password-strength.good:after {
font-family: fontAwesome;
font: var(--fa-font-solid);
content: '\f11a';
font-size: 18px;
margin-left: 10px;
}
.woocommerce-password-strength.strong {
background-color: #ffffff00;
border-color: #ffffff00;
text-align: right;
color: #00B86E;
padding: 5px;
}
.woocommerce-password-strength.strong:after {
font-family: fontAwesome;
font: var(--fa-font-solid);
content: '\f4da';
font-size: 18px;
margin-left: 10px;
}
.woocommerce-password-hint {
font-size: 12px;
line-height: 1.5em;
font-weight: 400;
color: #8C9099;
}
<link rel="stylesheet" type="text/css" href="https://my-website.com/wp-content/themes/theme-child/woocommerce/myaccount/assets/form-edit-account.css?<?php $FourDigitRandomNumber = mt_rand(00000,99999); echo $FourDigitRandomNumber; ?>" />
<script src="https://my-website.com/wp-content/themes/theme-child/woocommerce/myaccount/assets/form-edit-account.js?<?php $FourDigitRandomNumber = mt_rand(00000,99999); echo $FourDigitRandomNumber; ?>" defer=""></script>
<form action="" method="post" <?php do_action( 'woocommerce_edit_account_form_tag' );?> >
<?php do_action( 'woocommerce_edit_account_form_start' ); ?>
<div >
<p >
<label for="account_first_name">First Name<span >*</span></label>
<input type="text" name="account_first_name" id="account_first_name" autocomplete="given-name" value="John"/>
</p>
<p >
<label for="account_last_name">Last Name<span >*</span></label>
<input type="text" name="account_last_name" id="account_last_name" autocomplete="family-name" value="Doe" />
</p>
</div>
<div ></div>
<p >
<label for="account_user_login">Username</label>
<input type="text" name="account_user_login" id="account_user_login" disabled value="JohnDoe" /> <span >Description here</span>
</p>
<p >
<label for="account_display_name">Display Name<span >*</span></label>
<input type="text" name="account_display_name" id="account_display_name" value="JohnDoe" /> <span >This will be how your name will be displayed in the account section and in reviews</span>
</p>
<div ></div>
<p >
<label for="account_email">Email address<span >*</span></label>
<input type="email" name="account_email" id="account_email" autocomplete="email" value="[email protected]" />
</p>
<!-- Password Section -->
<div id="editpw" >Modifica Password<i ></i></div>
<div >
<fieldset>
<p>
<label for="password_current">Current password (leave blank to leave unchanged)</label>
<div >
<input type="password" name="password_current" id="password_current" autocomplete="off"/>
<input type="checkbox" id="pw_current" onclick="showPassword('password_current')"/>
<label for="pw_current" ></label>
</div>
</p>
<p>
<label for="password_1">New password (leave blank to leave unchanged)</label>
<div >
<input type="password" name="password_1" id="password_1" autocomplete="off"/>
<input type="checkbox" id="pw_1" onclick="showPassword('password_1')"/>
<label for="pw_1" ></label>
</div>
<div ></div>
</p>
<p>
<label for="password_2">Confirm new password</label>
<div >
<input type="password" name="password_2" id="password_2" autocomplete="off" />
<input type="checkbox" id="pw_2" onclick="showPassword('password_2')"/>
<label for="pw_2" ></label>
</div>
</p>
</fieldset>
</div>
<div ></div>
<?php do_action( 'woocommerce_edit_account_form' ); ?>
<p>
<?php wp_nonce_field( 'save_account_details', 'save-account-details-nonce' ); ?>
<button type="submit" name="save_account_details" value="<?php esc_attr_e( 'Save changes', 'woocommerce' ); ?>"><?php esc_html_e( 'Salva modifiche', 'woocommerce' ); ?></button>
<input type="hidden" name="action" value="save_account_details" />
</p>
<?php do_action( 'woocommerce_edit_account_form_end' ); ?>
</form>
<?php do_action( 'woocommerce_after_edit_account_form' ); ?>