(function($) { function __(string) { if (window.wflsi18n && typeof window.wflsi18n.__ === 'function') { return window.wflsi18n.__(string); } return WFLS_LOGIN_TRANSLATIONS[string] || string; } !function(Z){"use strict";Z.Zebra_Tooltips=function(t,l){var u,T,b,v,n={animation_speed:250,animation_offset:20,close_on_click:!0,content:!(this.version="2.1.0"),hide_delay:100,keep_visible:!0,max_width:250,opacity:".95",position:"center",prerender:!1,show_delay:100,vertical_alignment:"above",vertical_offset:0,onBeforeHide:null,onHide:null,onBeforeShow:null,onShow:null},r=this,_=function(e){var t,o,i,a,l,n,r,_,s,p,d,h,c,f,w=e.data("Zebra_Tooltip"),m=Z(window);return w.tooltip||(t=Z("
",{"class":"Zebra_Tooltip",css:{opacity:0,display:"block"}}),o=Z("
",{"class":"Zebra_Tooltip_Message",css:{maxWidth:w.max_width}}).html(w.content).appendTo(t),i=Z("
",{"class":"Zebra_Tooltip_Arrow"}).appendTo(t),a=Z("
").addClass("Zebra_Tooltip_Arrow_Border").appendTo(i),Z("
").appendTo(i),w.keep_visible&&(t.on("mouseleave"+(w.close_on_click?" click":""),function(){y(e)}),t.on("mouseenter",function(){g(e)})),t.appendTo("body"),w.sticky&&o.addClass("Zebra_Tooltip_Has_Close"),l=t.outerWidth(),n=t.outerHeight(),r=a.outerWidth(),_=a.outerHeight(),s=o.outerWidth(),p=o.outerHeight(),w={tooltip:t,tooltip_width:l,tooltip_height:n+_/2,message:o,arrow_container:i,arrow_width:r,arrow_height:_,arrow:a},t.css({width:w.tooltip_width,height:w.tooltip_height}),w.tooltip_width=w.tooltip_width+(o.outerWidth()-s),w.tooltip_height=w.tooltip_height+(o.outerHeight()-p),t.css({width:w.tooltip_width,height:w.tooltip_height,display:"none"}),w=Z.extend(e.data("Zebra_Tooltip"),w),e.data("Zebra_Tooltip",w)),w.sticky&&!w.close&&(Z("",{"class":"Zebra_Tooltip_Close",href:"javascript:void(0)"}).html("×").on("click",function(t){t.preventDefault();var o=e.data("Zebra_Tooltip");o.sticky=!1,e.data("Zebra_Tooltip",o),y(e)}).appendTo(w.message),w.close=!0,w=Z.extend(e.data("Zebra_Tooltip"),w),e.data("Zebra_Tooltip",w)),u=m.width(),T=m.height(),d=e.offset(),Z.extend(w,{element_left:d.left,element_top:d.top,element_width:e.outerWidth(),element_height:e.outerHeight()}),v=m.scrollTop(),b=m.scrollLeft(),h="left"===w.position?w.element_left-w.tooltip_width+w.arrow_width:"right"===w.position?w.element_left+w.element_width-w.arrow_width:w.element_left+(w.element_width-w.tooltip_width)/2,c=w.element_top-w.tooltip_height,f="left"===w.position?w.tooltip_width-w.arrow_width-w.arrow_width/2:"right"===w.position?w.arrow_width/2:(w.tooltip_width-w.arrow_width)/2,h+w.tooltip_width>u+b&&(f-=u+b-(h+w.tooltip_width)-6,h=u+b-w.tooltip_width-6,f+w.arrow_width>w.tooltip_width-6&&(f=w.tooltip_width-6-w.arrow_width),h+f+w.arrow_width/2w.element_left+w.element_width&&(f=-1e4)),w.message.css("margin-top",""),w.arrow_container.removeClass("Zebra_Tooltip_Arrow_Top").addClass("Zebra_Tooltip_Arrow_Bottom"),c'); tokenField.val(token); log.parent().append(tokenField); } } typeof actionCallback === 'function' && actionCallback(true); }); }); } else { var tokenField = $('#wfls-captcha-token'); if (tokenField.length) { tokenField.val('grecaptcha-missing'); } else { if (log.length) { tokenField = $(''); tokenField.val('grecaptcha-missing'); log.parent().append(tokenField); } } typeof actionCallback === 'function' && actionCallback(true); } }; function wfls_base64url_to_uint8array(base64url) { var padding = '='.repeat((4 - (base64url.length % 4)) % 4); var base64 = (base64url + padding).replace(/-/g, '+').replace(/_/g, '/'); var raw = window.atob(base64); var bytes = new Uint8Array(raw.length); for (var i = 0; i < raw.length; i++) { bytes[i] = raw.charCodeAt(i); } return bytes; } function wfls_arraybuffer_to_base64url(buffer) { var bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer); var binary = ''; for (var i = 0; i < bytes.length; i++) { binary += String.fromCharCode(bytes[i]); } return window.btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, ''); } function wfls_passkey_request_options_from_json(options) { var parsed = $.extend(true, {}, options); parsed.challenge = wfls_base64url_to_uint8array(parsed.challenge); if (parsed.allowCredentials && parsed.allowCredentials.length) { for (var i = 0; i < parsed.allowCredentials.length; i++) { parsed.allowCredentials[i].id = wfls_base64url_to_uint8array(parsed.allowCredentials[i].id); } } return parsed; } function wfls_assertion_to_json(assertion) { return { id: assertion.id, type: assertion.type, rawId: wfls_arraybuffer_to_base64url(assertion.rawId), response: { clientDataJSON: wfls_arraybuffer_to_base64url(assertion.response.clientDataJSON), authenticatorData: wfls_arraybuffer_to_base64url(assertion.response.authenticatorData), signature: wfls_arraybuffer_to_base64url(assertion.response.signature), userHandle: assertion.response.userHandle ? wfls_arraybuffer_to_base64url(assertion.response.userHandle) : null } }; } function wfls_passkey_error_message(error, fallback) { if (wfls_passkeys_require_https()) { return __('Passkey login requires HTTPS. Open this site using https:// and try again.'); } if (!error) { return fallback; } if (error.name && error.message) { return error.name + ': ' + error.message; } if (error.message) { return error.message; } return fallback; } function wfls_passkeys_require_https() { return window.location && window.location.protocol === 'http:' && window.location.hostname !== 'localhost'; } function wfls_passkey_redirect_target(form) { var redirect = form.find('input[name=redirect_to]').first(); if (redirect.length && redirect.val()) { return redirect.val(); } if ($('.woocommerce').length > 0) { return window.location.href; } return ''; } function wfls_is_interim_login(form) { var interim = form.find('input[name="interim-login"]').first(); return (interim.length && interim.val()) || window.location.search.indexOf('interim-login=1') >= 0; } function wfls_has_same_origin_parent_frame() { if (!window.parent || window.parent === window) { return false; } try { return window.parent.location.protocol === window.location.protocol && window.parent.location.host === window.location.host; } catch (e) { return false; } } function wfls_allows_same_relying_party_frame_login(form) { return !!wfls_is_interim_login(form) && wfls_has_same_origin_parent_frame(); } function wfls_complete_passkey_login(form, redirect) { if (wfls_is_interim_login(form)) { if (window.parent && window.parent !== window) { try { if (window.parent.jQuery) { window.parent.jQuery(window.parent).off('beforeunload.wp-auth-check'); } window.parent.location.reload(); return; } catch (e) {} } window.location.reload(); return; } window.location.href = redirect || window.location.href; } function wfls_begin_passkey_login_request(form, onSuccess, onError) { $.ajax({ type: 'POST', url: WFLSVars.ajaxurl, dataType: 'json', data: { action: 'wordfence_ls_begin_passkey_login', interim_login: wfls_allows_same_relying_party_frame_login(form) ? 1 : 0 }, success: function(json) { if (json.hasOwnProperty('error')) { onError(json.error); return; } onSuccess(json); }, error: function() { onError(__('An error was encountered while trying to start passkey login. Please try again.')); } }); } function wfls_post_finish_passkey_login(button, form, token, assertion) { var remember = false; form.find('input[name=rememberme], input[name=remember]').each(function() { if ($(this).is(':checkbox') && $(this).is(':checked')) { remember = true; } else if (!$(this).is(':checkbox') && $(this).val()) { remember = true; } }); $.ajax({ type: 'POST', url: WFLSVars.ajaxurl, dataType: 'json', data: { action: 'wordfence_ls_finish_passkey_login', token: token, credential: wfls_assertion_to_json(assertion), rememberme: remember ? 1 : 0, redirect_to: wfls_passkey_redirect_target(form) }, success: function(json) { button.prop('disabled', false).removeClass('disabled'); if (json.hasOwnProperty('error')) { showLoginMessage(json.error, 'error'); return; } wfls_complete_passkey_login(form, json.redirect || ''); }, error: function() { button.prop('disabled', false).removeClass('disabled'); showLoginMessage(__('An error was encountered while trying to authenticate with a passkey. Please try again.'), 'error'); } }); } function wfls_finish_passkey_login(button, form, token, assertion) { wfls_post_finish_passkey_login(button, form, token, assertion); } function wfls_start_passkey_login(button) { if (!loginLocator.locate()) { console.error('Required login elements not found'); return; } var form = loginLocator.getForm(); button.prop('disabled', true).addClass('disabled'); wfls_begin_passkey_login_request(form, function(json) { navigator.credentials.get({ publicKey: wfls_passkey_request_options_from_json(json.options) }).then(function(assertion) { wfls_finish_passkey_login(button, form, json.token, assertion); }).catch(function(error) { button.prop('disabled', false).removeClass('disabled'); if (error && error.name === 'NotAllowedError') { return; } showLoginMessage(wfls_passkey_error_message(error, __('Passkey login could not be completed.')), 'error'); }); }, function(message) { button.prop('disabled', false).removeClass('disabled'); showLoginMessage(message, 'error'); }); } function showLoginMessage(messageHtml, type) { $('.wfls-login-message').remove(); $('#wfls-login-modal').remove(); var heading = $('#login > h1'); if (heading.length > 0) { var dom = (type === 'error' ? $('
') : $('

')); dom.addClass('wfls-login-message'); dom.addClass('notice'); if (type === 'error') { dom.addClass('notice-error'); } dom.html(messageHtml); heading.after(dom); dom.get(0).scrollIntoView(); return; } else if ($('.woocommerce').length > 0){ var content = $('