diff --git a/assets/js/checkout.js b/assets/js/checkout.js index c071c2a4b..78679dfe5 100644 --- a/assets/js/checkout.js +++ b/assets/js/checkout.js @@ -873,6 +873,13 @@ this.request('wu_validate_form', form_data, function (results) { + // Safari/iOS autofill does NOT fire keyup/input events, so + // valid_password may be stale at submit time. Force a + // synchronous re-check before deciding to show the error. + if (! that.valid_password && that.password_strength_checker) { + that.password_strength_checker.checkStrength(); + } + if (! that.valid_password) { that.errors.push({ diff --git a/assets/js/wu-password-strength.js b/assets/js/wu-password-strength.js index 195cbfee6..bc94e5a4a 100644 --- a/assets/js/wu-password-strength.js +++ b/assets/js/wu-password-strength.js @@ -107,17 +107,38 @@ // Set initial message this.options.result.html(this.getStrengthLabel('empty')); - // Bind events - this.options.pass1.on('keyup input', function() { + // Bind events. + // Include 'change' for Safari/iOS autofill which does NOT fire + // keyup/input when auto-generating or pasting passwords (WebKit bug). + this.options.pass1.on('keyup input change', function() { self.checkStrength(); }); if (this.options.pass2 && this.options.pass2.length) { - this.options.pass2.on('keyup input', function() { + this.options.pass2.on('keyup input change', function() { self.checkStrength(); }); } + // Safari autofill detection — poll for value changes that bypass all + // DOM events (known WebKit bug). Stops after 60 seconds to avoid + // unnecessary CPU usage once the user has had time to fill the form. + this._lastPass1Val = ''; + this._autofillPoll = setInterval(function() { + var currentVal = self.options.pass1.val(); + if (currentVal !== self._lastPass1Val) { + self._lastPass1Val = currentVal; + self.checkStrength(); + } + }, 1000); + + setTimeout(function() { + if (self._autofillPoll) { + clearInterval(self._autofillPoll); + self._autofillPoll = null; + } + }, 60000); + // Disable submit initially if provided if (this.options.submit && this.options.submit.length) { this.options.submit.prop('disabled', true); diff --git a/assets/js/wu-password-strength.min.js b/assets/js/wu-password-strength.min.js index 64c0789a7..0d1da5fc0 100644 --- a/assets/js/wu-password-strength.min.js +++ b/assets/js/wu-password-strength.min.js @@ -1 +1 @@ -(t=>{function e(){var s={min_strength:4,enforce_rules:!1,min_length:12,require_uppercase:!1,require_lowercase:!1,require_number:!1,require_special:!1};return"undefined"==typeof wu_password_strength_settings?s:t.extend(s,wu_password_strength_settings)}window.WU_PasswordStrength=function(s){this.settings=e(),this.options=t.extend({pass1:null,pass2:null,result:null,submit:null,minStrength:parseInt(e().min_strength,10)||4,onValidityChange:null},s),this.isPasswordValid=!1,this.failedRules=[],this.init()},WU_PasswordStrength.prototype={init(){let s=this;this.options.pass1&&this.options.pass1.length&&(this.options.result&&this.options.result.length||(this.options.result=t("#pass-strength-result"),this.options.result.length))&&(this.options.result.html(this.getStrengthLabel("empty")),this.options.pass1.on("keyup input",function(){s.checkStrength()}),this.options.pass2&&this.options.pass2.length&&this.options.pass2.on("keyup input",function(){s.checkStrength()}),this.options.submit&&this.options.submit.length&&this.options.submit.prop("disabled",!0),this.checkStrength())},checkStrength(){var s,t=this.options.pass1.val(),e=this.options.pass2?this.options.pass2.val():"";this.options.result.attr("class","wu-py-2 wu-px-4 wu-block wu-text-sm wu-border-solid wu-border wu-mt-2"),t?(s=this.getDisallowedList(),t=wp.passwordStrength.meter(t,s,e),this.updateUI(t),this.updateValidity(t)):(this.options.result.addClass("wu-bg-gray-100 wu-border-gray-200").html(this.getStrengthLabel("empty")),this.setValid(!1))},getDisallowedList(){return"undefined"==typeof wp||void 0===wp.passwordStrength?[]:void 0===wp.passwordStrength.userInputDisallowedList?wp.passwordStrength.userInputBlacklist():wp.passwordStrength.userInputDisallowedList()},getStrengthLabel(s){var t;if("undefined"==typeof pwsL10n)return(t={empty:"Enter a password","-1":"Unknown",0:"Very weak",1:"Very weak",2:"Weak",3:"Medium",4:"Strong",super_strong:"Super Strong",5:"Mismatch"})[s]||t[0];switch(s){case"empty":return this.settings.i18n&&this.settings.i18n.empty?this.settings.i18n.empty:"Enter a password";case-1:return pwsL10n.unknown||"Unknown";case 0:case 1:return pwsL10n.short||"Very weak";case 2:return pwsL10n.bad||"Weak";case 3:return pwsL10n.good||"Medium";case 4:return pwsL10n.strong||"Strong";case"super_strong":return this.settings.i18n&&this.settings.i18n.super_strong?this.settings.i18n.super_strong:"Super Strong";case 5:return pwsL10n.mismatch||"Mismatch";default:return pwsL10n.short||"Very weak"}},updateUI(s){let t=this.getStrengthLabel(s),e="";switch(s){case-1:case 0:case 1:case 2:e="wu-bg-red-200 wu-border-red-300";break;case 3:e="wu-bg-yellow-200 wu-border-yellow-300";break;case 4:e="wu-bg-green-200 wu-border-green-300";break;default:e="wu-bg-red-200 wu-border-red-300"}this.settings.enforce_rules&&s>=this.options.minStrength&&5!==s&&(s=this.options.pass1.val(),s=this.checkPasswordRules(s),t=s.valid?(e="wu-bg-green-300 wu-border-green-400",this.getStrengthLabel("super_strong")):(e="wu-bg-red-200 wu-border-red-300",this.getRulesHint(s.failedRules))),this.options.result.addClass(e).html(t)},getRulesHint(s){var t=[],e=this.settings.i18n;return e?(-1!==s.indexOf("length")&&t.push(e.min_length.replace("%d",this.settings.min_length)),-1!==s.indexOf("uppercase")&&t.push(e.uppercase_letter),-1!==s.indexOf("lowercase")&&t.push(e.lowercase_letter),-1!==s.indexOf("number")&&t.push(e.number),-1!==s.indexOf("special")&&t.push(e.special_char),0===t.length?this.getStrengthLabel("super_strong"):e.required+" "+t.join(", ")):"Required: "+s.join(", ")},updateValidity(s){let t=!1;var e=this.options.pass1.val();(t=s>=this.options.minStrength&&5!==s?!0:t)&&this.settings.enforce_rules?(s=this.checkPasswordRules(e),t=s.valid,this.failedRules=s.failedRules):this.failedRules=[],this.setValid(t)},checkPasswordRules(s){var t=[],e=this.settings;return e.min_length&&s.length?~\[\]\/|`\\]/.test(s)&&t.push("special"),{valid:0===t.length,failedRules:t}},getFailedRules(){return this.failedRules},setValid(s){var t=this.isPasswordValid;this.isPasswordValid=s,this.options.submit&&this.options.submit.length&&this.options.submit.prop("disabled",!s),t!==s&&"function"==typeof this.options.onValidityChange&&this.options.onValidityChange(s)},isValid(){return this.isPasswordValid}}})(jQuery); \ No newline at end of file +(e=>{function t(){var s={min_strength:4,enforce_rules:!1,min_length:12,require_uppercase:!1,require_lowercase:!1,require_number:!1,require_special:!1};return"undefined"==typeof wu_password_strength_settings?s:e.extend(s,wu_password_strength_settings)}window.WU_PasswordStrength=function(s){this.settings=t(),this.options=e.extend({pass1:null,pass2:null,result:null,submit:null,minStrength:parseInt(t().min_strength,10)||4,onValidityChange:null},s),this.isPasswordValid=!1,this.failedRules=[],this.init()},WU_PasswordStrength.prototype={init(){let t=this;this.options.pass1&&this.options.pass1.length&&(this.options.result&&this.options.result.length||(this.options.result=e("#pass-strength-result"),this.options.result.length))&&(this.options.result.html(this.getStrengthLabel("empty")),this.options.pass1.on("keyup input change",function(){t.checkStrength()}),this.options.pass2&&this.options.pass2.length&&this.options.pass2.on("keyup input change",function(){t.checkStrength()}),this._lastPass1Val="",this._autofillPoll=setInterval(function(){var s=t.options.pass1.val();s!==t._lastPass1Val&&(t._lastPass1Val=s,t.checkStrength())},1e3),setTimeout(function(){t._autofillPoll&&(clearInterval(t._autofillPoll),t._autofillPoll=null)},6e4),this.options.submit&&this.options.submit.length&&this.options.submit.prop("disabled",!0),this.checkStrength())},checkStrength(){var s,t=this.options.pass1.val(),e=this.options.pass2?this.options.pass2.val():"";this.options.result.attr("class","wu-py-2 wu-px-4 wu-block wu-text-sm wu-border-solid wu-border wu-mt-2"),t?(s=this.getDisallowedList(),t=wp.passwordStrength.meter(t,s,e),this.updateUI(t),this.updateValidity(t)):(this.options.result.addClass("wu-bg-gray-100 wu-border-gray-200").html(this.getStrengthLabel("empty")),this.setValid(!1))},getDisallowedList(){return"undefined"==typeof wp||void 0===wp.passwordStrength?[]:void 0===wp.passwordStrength.userInputDisallowedList?wp.passwordStrength.userInputBlacklist():wp.passwordStrength.userInputDisallowedList()},getStrengthLabel(s){var t;if("undefined"==typeof pwsL10n)return(t={empty:"Enter a password","-1":"Unknown",0:"Very weak",1:"Very weak",2:"Weak",3:"Medium",4:"Strong",super_strong:"Super Strong",5:"Mismatch"})[s]||t[0];switch(s){case"empty":return this.settings.i18n&&this.settings.i18n.empty?this.settings.i18n.empty:"Enter a password";case-1:return pwsL10n.unknown||"Unknown";case 0:case 1:return pwsL10n.short||"Very weak";case 2:return pwsL10n.bad||"Weak";case 3:return pwsL10n.good||"Medium";case 4:return pwsL10n.strong||"Strong";case"super_strong":return this.settings.i18n&&this.settings.i18n.super_strong?this.settings.i18n.super_strong:"Super Strong";case 5:return pwsL10n.mismatch||"Mismatch";default:return pwsL10n.short||"Very weak"}},updateUI(s){let t=this.getStrengthLabel(s),e="";switch(s){case-1:case 0:case 1:case 2:e="wu-bg-red-200 wu-border-red-300";break;case 3:e="wu-bg-yellow-200 wu-border-yellow-300";break;case 4:e="wu-bg-green-200 wu-border-green-300";break;default:e="wu-bg-red-200 wu-border-red-300"}this.settings.enforce_rules&&s>=this.options.minStrength&&5!==s&&(s=this.options.pass1.val(),s=this.checkPasswordRules(s),t=s.valid?(e="wu-bg-green-300 wu-border-green-400",this.getStrengthLabel("super_strong")):(e="wu-bg-red-200 wu-border-red-300",this.getRulesHint(s.failedRules))),this.options.result.addClass(e).html(t)},getRulesHint(s){var t=[],e=this.settings.i18n;return e?(-1!==s.indexOf("length")&&t.push(e.min_length.replace("%d",this.settings.min_length)),-1!==s.indexOf("uppercase")&&t.push(e.uppercase_letter),-1!==s.indexOf("lowercase")&&t.push(e.lowercase_letter),-1!==s.indexOf("number")&&t.push(e.number),-1!==s.indexOf("special")&&t.push(e.special_char),0===t.length?this.getStrengthLabel("super_strong"):e.required+" "+t.join(", ")):"Required: "+s.join(", ")},updateValidity(s){let t=!1;var e=this.options.pass1.val();(t=s>=this.options.minStrength&&5!==s?!0:t)&&this.settings.enforce_rules?(s=this.checkPasswordRules(e),t=s.valid,this.failedRules=s.failedRules):this.failedRules=[],this.setValid(t)},checkPasswordRules(s){var t=[],e=this.settings;return e.min_length&&s.length?~\[\]\/|`\\]/.test(s)&&t.push("special"),{valid:0===t.length,failedRules:t}},getFailedRules(){return this.failedRules},setValid(s){var t=this.isPasswordValid;this.isPasswordValid=s,this.options.submit&&this.options.submit.length&&this.options.submit.prop("disabled",!s),t!==s&&"function"==typeof this.options.onValidityChange&&this.options.onValidityChange(s)},isValid(){return this.isPasswordValid}}})(jQuery); \ No newline at end of file