mirror of
https://github.com/processwire/processwire.git
synced 2025-08-11 17:24:46 +02:00
Add feature request processwire/processwire-requests#203 support for password unmask in InputfieldPassword
This commit is contained in:
@@ -168,6 +168,25 @@ jQuery(document).ready(function($) {
|
||||
}
|
||||
if($on) $on.addClass('on').siblings('.on').removeClass('on');
|
||||
});
|
||||
|
||||
var $passMask = $inputfield.find('.pass-mask');
|
||||
if($passMask.length) {
|
||||
var $passMaskShow = $passMask.find('.pass-mask-show');
|
||||
var $passMaskHide = $passMask.find('.pass-mask-hide');
|
||||
$passMaskHide.hide();
|
||||
$passMaskShow.on('click', function(e) {
|
||||
$(this).hide();
|
||||
$passMaskHide.show();
|
||||
$inputfield.find('input[type=password]').prop('type', 'text').addClass('pass-unmask');
|
||||
return false;
|
||||
});
|
||||
$passMaskHide.hide().on('click', function(e) {
|
||||
$(this).hide();
|
||||
$passMaskShow.show();
|
||||
$inputfield.find('input.pass-unmask').prop('type', 'password').removeClass('pass-unmask');
|
||||
return false;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// accommodate issue where Firefox auto-populates remembered password when it shouldn't
|
||||
|
@@ -1 +1 @@
|
||||
jQuery(document).ready(function($){var $inputs=$("input.InputfieldPasswordComplexify");$inputs.each(function(){var $input=$(this);var $inputfield=$input.closest(".Inputfield");var $confirm=$inputfield.find(".InputfieldPasswordConfirm");var $confirms=$confirm.next(".pass-confirm");var $inputOld=$inputfield.find("input.InputfieldPasswordOld");var $wrapScores=$input.siblings(".pass-scores");var $percent=$input.siblings(".pass-percent");var $scores=$wrapScores.children();var requirements=$wrapScores.attr("data-requirements").split(" ");var minlength=parseInt($input.attr("data-minlength"));var inputOldEvent;var options={banMode:$input.attr("data-banMode"),strengthScaleFactor:parseFloat($input.attr("data-factor")),minimumChars:minlength};if($inputOld.length){$input.attr("disabled","disabled");inputOldEvent=function(){if($(this).val().length>0){$inputOld.off("keyup input change blur",inputOldEvent);$input.removeAttr("disabled")}};$inputOld.on("keyup input change blur",inputOldEvent)}if($confirm.length)$confirm.attr("disabled","disabled");$input.complexify(options,function(valid,complexity){var $on=null;var val=$input.val();var len=val.length;var numGood=0;if(len>0){for(var n=0;n<requirements.length;n++){var fail=false;var requirement=requirements[n];var $requirement=$inputfield.find(".pass-require-"+requirement);var re;if(requirement=="letter"){re=XRegExp("\\p{L}");if(!re.test(val))fail=true}else if(requirement=="upper"){re=XRegExp("\\p{Lu}");if(!re.test(val))fail=true}else if(requirement=="lower"){re=XRegExp("\\p{Ll}");if(!re.test(val))fail=true}else if(requirement=="digit"){re=XRegExp("\\p{N}");if(!re.test(val))fail=true}else if(requirement=="other"){re=XRegExp("\\p{P}");var rx=XRegExp("\\p{S}");if(!re.test(val)&&!rx.test(val))fail=true}else if(requirement=="space"){re=XRegExp("\\p{Z}");if(!re.test(val))fail=true}else if(requirement=="minlength"){if(len<minlength)fail=true}if(fail){$requirement.removeClass("pass-require-good ui-priority-secondary")}else{$requirement.addClass("pass-require-good ui-priority-secondary");numGood++}}}else{$inputfield.find(".pass-require-good").removeClass("pass-require-good ui-priority-secondary")}if(len==0){$scores.removeClass("on");return}else if($inputOld.length&&$inputOld.val()===$input.val()){$on=$scores.filter(".pass-same")}else if(numGood<requirements.length){$on=$scores.filter(".pass-fail")}else if(len<minlength){$on=$scores.filter(".pass-short")}else if(!valid){$on=$scores.filter(".pass-common")}else if(complexity==0){$on=$scores.filter(".pass-invalid")}else if(complexity<50){$on=$scores.filter(".pass-weak")}else if(complexity<70){$on=$scores.filter(".pass-medium")}else if(complexity<100){$on=$scores.filter(".pass-good")}else if(complexity==100){$on=$scores.filter(".pass-excellent")}if($on&&!$on.hasClass("on")){$on.siblings(".on").removeClass("on");$on.addClass("on")}if($on.hasClass("pass-fail")||$on.hasClass("pass-short")||$on.hasClass("pass-common")||$on.hasClass("pass-invalid")||$on.hasClass("pass-same")){$confirm.attr("disabled","disabled").val("").change()}else{$confirm.removeAttr("disabled");$on.find("small").remove();$on.append("<small style='margin-left:0.5em'>("+Math.floor(complexity)+"%)</small>")}if($confirm.val().length){$confirm.change()}});$input.on("change",function(){var val=$(this).val();if(val.length>0){$input.attr("required","required");$confirm.attr("required","required")}else if(!$(this).closest(".InputfieldStateRequired").length){$input.removeAttr("required");$confirm.removeAttr("required")}});$confirm.on("keyup change",function(){var val1=$input.val();var val2=$(this).val();var $on=null;var $p=$input.closest("p").removeClass("pass-matches");if(val2.length==0){$on=$confirms.children(".confirm-pending")}else if(val1==val2){$on=$confirms.children(".confirm-yes");$p.addClass("pass-matches")}else if(val1.indexOf(val2)===0){$on=$confirms.children(".confirm-qty");$on.children("span").html(val2.length+"/"+val1.length)}else{$on=$confirms.children(".confirm-no")}if($on)$on.addClass("on").siblings(".on").removeClass("on")})});var $ffinputs=$(".InputfieldPassword").find("input[autocomplete='new-password']");if($ffinputs.length){setTimeout(function(){$ffinputs.each(function(){if($(this).val().length<1||$(this).attr("value").length>0)return;$(this).val("").trigger("keyup").change().closest(".Inputfield").removeClass("InputfieldStateChanged")})},1e3)}});
|
||||
jQuery(document).ready(function($){var $inputs=$("input.InputfieldPasswordComplexify");$inputs.each(function(){var $input=$(this);var $inputfield=$input.closest(".Inputfield");var $confirm=$inputfield.find(".InputfieldPasswordConfirm");var $confirms=$confirm.next(".pass-confirm");var $inputOld=$inputfield.find("input.InputfieldPasswordOld");var $wrapScores=$input.siblings(".pass-scores");var $percent=$input.siblings(".pass-percent");var $scores=$wrapScores.children();var requirements=$wrapScores.attr("data-requirements").split(" ");var minlength=parseInt($input.attr("data-minlength"));var inputOldEvent;var options={banMode:$input.attr("data-banMode"),strengthScaleFactor:parseFloat($input.attr("data-factor")),minimumChars:minlength};if($inputOld.length){$input.attr("disabled","disabled");inputOldEvent=function(){if($(this).val().length>0){$inputOld.off("keyup input change blur",inputOldEvent);$input.removeAttr("disabled")}};$inputOld.on("keyup input change blur",inputOldEvent)}if($confirm.length)$confirm.attr("disabled","disabled");$input.complexify(options,function(valid,complexity){var $on=null;var val=$input.val();var len=val.length;var numGood=0;if(len>0){for(var n=0;n<requirements.length;n++){var fail=false;var requirement=requirements[n];var $requirement=$inputfield.find(".pass-require-"+requirement);var re;if(requirement=="letter"){re=XRegExp("\\p{L}");if(!re.test(val))fail=true}else if(requirement=="upper"){re=XRegExp("\\p{Lu}");if(!re.test(val))fail=true}else if(requirement=="lower"){re=XRegExp("\\p{Ll}");if(!re.test(val))fail=true}else if(requirement=="digit"){re=XRegExp("\\p{N}");if(!re.test(val))fail=true}else if(requirement=="other"){re=XRegExp("\\p{P}");var rx=XRegExp("\\p{S}");if(!re.test(val)&&!rx.test(val))fail=true}else if(requirement=="space"){re=XRegExp("\\p{Z}");if(!re.test(val))fail=true}else if(requirement=="minlength"){if(len<minlength)fail=true}if(fail){$requirement.removeClass("pass-require-good ui-priority-secondary")}else{$requirement.addClass("pass-require-good ui-priority-secondary");numGood++}}}else{$inputfield.find(".pass-require-good").removeClass("pass-require-good ui-priority-secondary")}if(len==0){$scores.removeClass("on");return}else if($inputOld.length&&$inputOld.val()===$input.val()){$on=$scores.filter(".pass-same")}else if(numGood<requirements.length){$on=$scores.filter(".pass-fail")}else if(len<minlength){$on=$scores.filter(".pass-short")}else if(!valid){$on=$scores.filter(".pass-common")}else if(complexity==0){$on=$scores.filter(".pass-invalid")}else if(complexity<50){$on=$scores.filter(".pass-weak")}else if(complexity<70){$on=$scores.filter(".pass-medium")}else if(complexity<100){$on=$scores.filter(".pass-good")}else if(complexity==100){$on=$scores.filter(".pass-excellent")}if($on&&!$on.hasClass("on")){$on.siblings(".on").removeClass("on");$on.addClass("on")}if($on.hasClass("pass-fail")||$on.hasClass("pass-short")||$on.hasClass("pass-common")||$on.hasClass("pass-invalid")||$on.hasClass("pass-same")){$confirm.attr("disabled","disabled").val("").change()}else{$confirm.removeAttr("disabled");$on.find("small").remove();$on.append("<small style='margin-left:0.5em'>("+Math.floor(complexity)+"%)</small>")}if($confirm.val().length){$confirm.change()}});$input.on("change",function(){var val=$(this).val();if(val.length>0){$input.attr("required","required");$confirm.attr("required","required")}else if(!$(this).closest(".InputfieldStateRequired").length){$input.removeAttr("required");$confirm.removeAttr("required")}});$confirm.on("keyup change",function(){var val1=$input.val();var val2=$(this).val();var $on=null;var $p=$input.closest("p").removeClass("pass-matches");if(val2.length==0){$on=$confirms.children(".confirm-pending")}else if(val1==val2){$on=$confirms.children(".confirm-yes");$p.addClass("pass-matches")}else if(val1.indexOf(val2)===0){$on=$confirms.children(".confirm-qty");$on.children("span").html(val2.length+"/"+val1.length)}else{$on=$confirms.children(".confirm-no")}if($on)$on.addClass("on").siblings(".on").removeClass("on")});var $passMask=$inputfield.find(".pass-mask");if($passMask.length){var $passMaskShow=$passMask.find(".pass-mask-show");var $passMaskHide=$passMask.find(".pass-mask-hide");$passMaskHide.hide();$passMaskShow.on("click",function(e){$(this).hide();$passMaskHide.show();$inputfield.find("input[type=password]").prop("type","text").addClass("pass-unmask");return false});$passMaskHide.hide().on("click",function(e){$(this).hide();$passMaskShow.show();$inputfield.find("input.pass-unmask").prop("type","password").removeClass("pass-unmask");return false})}});var $ffinputs=$(".InputfieldPassword").find("input[autocomplete='new-password']");if($ffinputs.length){setTimeout(function(){$ffinputs.each(function(){if($(this).val().length<1||$(this).attr("value").length>0)return;$(this).val("").trigger("keyup").change().closest(".Inputfield").removeClass("InputfieldStateChanged")})},1e3)}});
|
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* An Inputfield for handling a password
|
||||
*
|
||||
* ProcessWire 3.x, Copyright 2020 by Ryan Cramer
|
||||
* ProcessWire 3.x, Copyright 2021 by Ryan Cramer
|
||||
* https://processwire.com
|
||||
*
|
||||
* @property array $requirements Array of requirements (See require* constants)
|
||||
@@ -12,6 +12,7 @@
|
||||
* @property float $complexifyFactor Complexify factor, lower numbers enable simpler passwords (default=0.7)
|
||||
* @property int $requireOld Require previous password? 0=Auto, 1=Yes, -1=No, Default=0 (Auto)
|
||||
* @property bool $showPass Allow password to be rendered in renderValue and/or re-populated in form?
|
||||
* @property bool $unmask Allow passwords to be unmasked? (3.0.173+)
|
||||
* @property string $defaultLabel Default label for field (default='Set Password'). Used when no 'label' has been set.
|
||||
* @property string $oldPassLabel Label for old/current password placeholder.
|
||||
* @property string $newPassLabel Label for new password placeholder.
|
||||
@@ -114,6 +115,7 @@ class InputfieldPassword extends InputfieldText {
|
||||
self::requireNone => $this->_('none (disable all above)'),
|
||||
));
|
||||
$this->set('showPass', false); // allow password to be rendered in renderValue and/or re-populated in form?
|
||||
$this->set('unmask', false);
|
||||
$this->set('oldPassLabel', $this->_('Current password'));
|
||||
$this->set('newPassLabel', $this->_('New password'));
|
||||
$this->set('confirmLabel', $this->_('Confirm'));
|
||||
@@ -263,6 +265,14 @@ class InputfieldPassword extends InputfieldText {
|
||||
"</span>" .
|
||||
"</p>";
|
||||
|
||||
if($this->unmask) {
|
||||
$out .=
|
||||
"<p class='pass-mask detail'>" .
|
||||
"<a class='pass-mask-show' href='#'>" . $this->_('Show Password') . "</a>" .
|
||||
"<a class='pass-mask-hide' href='#'>" . $this->_('Hide Password') . "</a>" .
|
||||
"</p>";
|
||||
}
|
||||
|
||||
$this->attr('value', $value);
|
||||
if($trackChanges) $this->setTrackChanges(true);
|
||||
|
||||
@@ -449,13 +459,14 @@ class InputfieldPassword extends InputfieldText {
|
||||
'maxlength',
|
||||
'showCount',
|
||||
'size',
|
||||
);
|
||||
);
|
||||
|
||||
foreach($skips as $name) {
|
||||
$f = $inputfields->get($name);
|
||||
if($f) $inputfields->remove($f);
|
||||
}
|
||||
|
||||
/** @var InputfieldCheckboxes $f */
|
||||
$f = $this->wire('modules')->get('InputfieldCheckboxes');
|
||||
$f->attr('name', 'requirements');
|
||||
$f->label = $this->_('Password requirements');
|
||||
@@ -468,6 +479,7 @@ class InputfieldPassword extends InputfieldText {
|
||||
$f->columnWidth = 50;
|
||||
$inputfields->add($f);
|
||||
|
||||
/** @var InputfieldRadios $f */
|
||||
$f = $this->wire('modules')->get('InputfieldRadios');
|
||||
$f->attr('name', 'complexifyBanMode');
|
||||
$f->label = $this->_('Word ban mode');
|
||||
@@ -478,6 +490,7 @@ class InputfieldPassword extends InputfieldText {
|
||||
$f->columnWidth = 50;
|
||||
$inputfields->add($f);
|
||||
|
||||
/** @var InputfieldFloat $f */
|
||||
$f = $this->wire('modules')->get('InputfieldFloat');
|
||||
$f->attr('name', 'complexifyFactor');
|
||||
$f->label = $this->_('Complexify factor');
|
||||
@@ -488,6 +501,7 @@ class InputfieldPassword extends InputfieldText {
|
||||
$f->columnWidth = 50;
|
||||
$inputfields->add($f);
|
||||
|
||||
/** @var InputfieldInteger $f */
|
||||
$f = $this->wire('modules')->get('InputfieldInteger');
|
||||
$f->attr('name', 'minlength');
|
||||
$f->label = $this->_('Minimum password length');
|
||||
@@ -497,6 +511,7 @@ class InputfieldPassword extends InputfieldText {
|
||||
$inputfields->add($f);
|
||||
|
||||
if(!$this->getSetting('hasFieldtype')) {
|
||||
/** @var InputfieldCheckbox $f */
|
||||
$f = $this->wire('modules')->get('InputfieldCheckbox');
|
||||
$f->attr('name', 'showPass');
|
||||
$f->label = $this->_('Allow existing passwords to be shown and/or rendered in form?');
|
||||
@@ -504,6 +519,7 @@ class InputfieldPassword extends InputfieldText {
|
||||
$inputfields->add($f);
|
||||
}
|
||||
|
||||
/** @var InputfieldRadios $f */
|
||||
$f = $this->wire('modules')->get('InputfieldRadios');
|
||||
$f->attr('name', 'requireOld');
|
||||
$f->label = $this->_('Require old password before allowing changes?');
|
||||
@@ -515,6 +531,16 @@ class InputfieldPassword extends InputfieldText {
|
||||
$f->attr('value', (int) $this->requireOld);
|
||||
$inputfields->add($f);
|
||||
|
||||
$f = $this->wire()->modules->get('InputfieldRadios');
|
||||
$f->attr('name', 'unmask');
|
||||
$f->label = $this->_('Allow user to show/unmask password during changes?');
|
||||
$f->description = $this->_('Provides a show/hide password control so users can see what they type when in an appropriate environment.');
|
||||
$f->addOption(1, $this->_('Yes'));
|
||||
$f->addOption(0, $this->_('No'));
|
||||
$f->optionColumns = 1;
|
||||
$f->attr('value', (int) $this->unmask);
|
||||
$inputfields->add($f);
|
||||
|
||||
return $inputfields;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user