diff --git a/wp-content/plugins/wp-webauthn/blocks/blocks.build.js b/wp-content/plugins/wp-webauthn/blocks/blocks.build.js index e2b2005c..f0ccee1a 100644 --- a/wp-content/plugins/wp-webauthn/blocks/blocks.build.js +++ b/wp-content/plugins/wp-webauthn/blocks/blocks.build.js @@ -1 +1 @@ -!function(e){function t(a){if(n[a])return n[a].exports;var o=n[a]={i:a,l:!1,exports:{}};return e[a].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};t.m=e,t.c=n,t.d=function(e,n,a){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:a})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=0)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});n(1)},function(e,t,n){"use strict";var a=n(2),o=(n.n(a),wp.i18n.__),r=wp.blocks.registerBlockType;r("wp-webauthn/login",{title:o("WebAuthn Login Form","wp-webauthn"),icon:"admin-network",category:"widgets",keywords:["WebAuthn",o("Login Form","wp-webauthn")],attributes:{traditional:{type:"boolean",default:!0},username:{type:"string"},autoHide:{type:"boolean",default:!0},to:{type:"string"}},edit:function(e){var t=e.attributes,n=e.setAttributes,r=e.className;return wp.element.createElement("div",{className:r,style:{padding:"20px",boxSizing:"border-box",backgroundColor:"#F4F4F4",borderRadius:"3px"}},wp.element.createElement("span",{style:{fontSize:"15px",marginBottom:"20px",opacity:".5"}},o("WebAuthn Login Form","wp-webauthn")),wp.element.createElement(a.TextControl,{label:o("Default username","wp-webauthn"),value:t.username,onChange:function(e){n({username:e})}}),wp.element.createElement(a.TextControl,{label:o("Redirect to","wp-webauthn"),value:t.to,onChange:function(e){n({to:e})}}),wp.element.createElement(a.CheckboxControl,{label:o("Show password form as well","wp-webauthn"),checked:t.traditional,onChange:function(e){n({traditional:e})}}),wp.element.createElement(a.CheckboxControl,{label:o("Hide for logged-in users","wp-webauthn"),checked:t.autoHide,onChange:function(e){n({autoHide:e})}}))},save:function(e){var t=e.attributes;return'[wwa_login_form traditional="'+t.traditional+'" username="'+t.username+'" auto_hide="'+t.autoHide+'" to="'+t.to+'"]'}}),r("wp-webauthn/register",{title:o("WebAuthn Register Form","wp-webauthn"),icon:"plus-alt",category:"widgets",keywords:["WebAuthn",o("Register Form","wp-webauthn")],attributes:{display:{type:"boolean",default:!0}},edit:function(e){var t=e.attributes,n=e.setAttributes,r=e.className;return wp.element.createElement("div",{className:r,style:{padding:"20px",boxSizing:"border-box",backgroundColor:"#F4F4F4",borderRadius:"3px"}},wp.element.createElement("span",{style:{fontSize:"15px",marginBottom:"20px",opacity:".5"}},o("WebAuthn Register Form","wp-webauthn")),wp.element.createElement("div",{className:r,style:{height:"150px",display:"flex",justifyContent:"center",alignItems:"center"}},wp.element.createElement(a.CheckboxControl,{label:o("Show a message for users who doesn't logged-in","wp-webauthn"),checked:t.display,onChange:function(e){n({display:e})}})))},save:function(e){return'[wwa_register_form display="'+e.attributes.display+'"]'}}),r("wp-webauthn/verify",{title:o("WebAuthn Verify Buttons","wp-webauthn"),icon:"sos",category:"widgets",keywords:["WebAuthn",o("Verify Buttons","wp-webauthn")],attributes:{display:{type:"boolean",default:!0}},edit:function(e){var t=e.attributes,n=e.setAttributes,r=e.className;return wp.element.createElement("div",{className:r,style:{padding:"20px",boxSizing:"border-box",backgroundColor:"#F4F4F4",borderRadius:"3px"}},wp.element.createElement("span",{style:{fontSize:"15px",marginBottom:"20px",opacity:".5"}},o("WebAuthn Verify Buttons","wp-webauthn")),wp.element.createElement("div",{className:r,style:{height:"50px",display:"flex",justifyContent:"center",alignItems:"center"}},wp.element.createElement(a.CheckboxControl,{label:o("Show a message for users who doesn't logged-in","wp-webauthn"),checked:t.display,onChange:function(e){n({display:e})}})))},save:function(e){return'[wwa_verify_button display="'+e.attributes.display+'"]'}}),r("wp-webauthn/list",{title:o("WebAuthn Authenticator List","wp-webauthn"),icon:"menu",category:"widgets",keywords:["WebAuthn",o("Authenticator List","wp-webauthn")],attributes:{display:{type:"boolean",default:!0}},edit:function(e){var t=e.attributes,n=e.setAttributes,r=e.className;return wp.element.createElement("div",{className:r,style:{padding:"20px",boxSizing:"border-box",backgroundColor:"#F4F4F4",borderRadius:"3px"}},wp.element.createElement("span",{style:{fontSize:"15px",marginBottom:"20px",opacity:".5"}},o("WebAuthn Authenticator List","wp-webauthn")),wp.element.createElement("div",{className:r,style:{height:"150px",display:"flex",justifyContent:"center",alignItems:"center"}},wp.element.createElement(a.CheckboxControl,{label:o("Show a message for users who doesn't logged-in","wp-webauthn"),checked:t.display,onChange:function(e){n({display:e})}})))},save:function(e){return'[wwa_list display="'+e.attributes.display+'"]'}})},function(e,t){e.exports=wp.components}]); \ No newline at end of file +!function(e){function t(a){if(n[a])return n[a].exports;var o=n[a]={i:a,l:!1,exports:{}};return e[a].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};t.m=e,t.c=n,t.d=function(e,n,a){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:a})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=0)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});n(1)},function(e,t,n){"use strict";var a=n(2),__=(n.n(a),wp.i18n.__),o=wp.blocks.registerBlockType;o("wp-webauthn/login",{title:__("WebAuthn Login Form","wp-webauthn"),icon:"admin-network",category:"widgets",keywords:["WebAuthn",__("Login Form","wp-webauthn")],attributes:{traditional:{type:"boolean",default:!0},username:{type:"string",default:""},autoHide:{type:"boolean",default:!0},to:{type:"string",default:""}},edit:function(e){var t=e.attributes,n=e.setAttributes,o=e.className;return wp.element.createElement("div",{className:o,style:{padding:"20px",boxSizing:"border-box",backgroundColor:"#F4F4F4",borderRadius:"3px"}},wp.element.createElement("span",{style:{fontSize:"15px",marginBottom:"20px",opacity:".5"}},__("WebAuthn Login Form","wp-webauthn")),wp.element.createElement(a.TextControl,{label:__("Default username","wp-webauthn"),value:t.username,onChange:function(e){n({username:e})}}),wp.element.createElement(a.TextControl,{label:__("Redirect to","wp-webauthn"),value:t.to,onChange:function(e){n({to:e})}}),wp.element.createElement(a.CheckboxControl,{label:__("Show password form as well","wp-webauthn"),checked:t.traditional,onChange:function(e){n({traditional:e})}}),wp.element.createElement(a.CheckboxControl,{label:__("Hide for logged-in users","wp-webauthn"),checked:t.autoHide,onChange:function(e){n({autoHide:e})}}))},save:function(e){var t=e.attributes;return'[wwa_login_form traditional="'+t.traditional+'" auto_hide="'+t.autoHide+'"'+(t.username?' username="'+t.username+'"':"")+(t.to?' to="'+t.to+'"':"")+"]"}}),o("wp-webauthn/register",{title:__("WebAuthn Register Form","wp-webauthn"),icon:"plus-alt",category:"widgets",keywords:["WebAuthn",__("Register Form","wp-webauthn")],attributes:{display:{type:"boolean",default:!0}},edit:function(e){var t=e.attributes,n=e.setAttributes,o=e.className;return wp.element.createElement("div",{className:o,style:{padding:"20px",boxSizing:"border-box",backgroundColor:"#F4F4F4",borderRadius:"3px"}},wp.element.createElement("span",{style:{fontSize:"15px",marginBottom:"20px",opacity:".5"}},__("WebAuthn Register Form","wp-webauthn")),wp.element.createElement("div",{className:o,style:{height:"150px",display:"flex",justifyContent:"center",alignItems:"center"}},wp.element.createElement(a.CheckboxControl,{label:__("Show a message for users who doesn't logged-in","wp-webauthn"),checked:t.display,onChange:function(e){n({display:e})}})))},save:function(e){return'[wwa_register_form display="'+e.attributes.display+'"]'}}),o("wp-webauthn/verify",{title:__("WebAuthn Verify Buttons","wp-webauthn"),icon:"sos",category:"widgets",keywords:["WebAuthn",__("Verify Buttons","wp-webauthn")],attributes:{display:{type:"boolean",default:!0}},edit:function(e){var t=e.attributes,n=e.setAttributes,o=e.className;return wp.element.createElement("div",{className:o,style:{padding:"20px",boxSizing:"border-box",backgroundColor:"#F4F4F4",borderRadius:"3px"}},wp.element.createElement("span",{style:{fontSize:"15px",marginBottom:"20px",opacity:".5"}},__("WebAuthn Verify Buttons","wp-webauthn")),wp.element.createElement("div",{className:o,style:{height:"50px",display:"flex",justifyContent:"center",alignItems:"center"}},wp.element.createElement(a.CheckboxControl,{label:__("Show a message for users who doesn't logged-in","wp-webauthn"),checked:t.display,onChange:function(e){n({display:e})}})))},save:function(e){return'[wwa_verify_button display="'+e.attributes.display+'"]'}}),o("wp-webauthn/list",{title:__("WebAuthn Authenticator List","wp-webauthn"),icon:"menu",category:"widgets",keywords:["WebAuthn",__("Authenticator List","wp-webauthn")],attributes:{display:{type:"boolean",default:!0}},edit:function(e){var t=e.attributes,n=e.setAttributes,o=e.className;return wp.element.createElement("div",{className:o,style:{padding:"20px",boxSizing:"border-box",backgroundColor:"#F4F4F4",borderRadius:"3px"}},wp.element.createElement("span",{style:{fontSize:"15px",marginBottom:"20px",opacity:".5"}},__("WebAuthn Authenticator List","wp-webauthn")),wp.element.createElement("div",{className:o,style:{height:"150px",display:"flex",justifyContent:"center",alignItems:"center"}},wp.element.createElement(a.CheckboxControl,{label:__("Show a message for users who doesn't logged-in","wp-webauthn"),checked:t.display,onChange:function(e){n({display:e})}})))},save:function(e){return'[wwa_list display="'+e.attributes.display+'"]'}})},function(e,t){e.exports=wp.components}]); \ No newline at end of file diff --git a/wp-content/plugins/wp-webauthn/js/frontend.js b/wp-content/plugins/wp-webauthn/js/frontend.js index 5cd61d97..33610dff 100644 --- a/wp-content/plugins/wp-webauthn/js/frontend.js +++ b/wp-content/plugins/wp-webauthn/js/frontend.js @@ -5,7 +5,7 @@ const wwa_ajax = function () { let xmlHttpReq = new XMLHttpRequest(); return { /** Send an AJAX GET request and get the response - * + * * @param {string} url URL * @param {string} data Attached data * @param {object} callback Callback function @@ -15,14 +15,14 @@ const wwa_ajax = function () { xmlHttpReq.send(); xmlHttpReq.onreadystatechange = () => { if (xmlHttpReq.readyState === 4 && xmlHttpReq.status === 200) { - callback(xmlHttpReq.responseText, true); + callback(xmlHttpReq.responseText.trim(), true); } else if (xmlHttpReq.readyState === 4) { callback('Network Error.', false); } } }, /** Send an AJAX POST request and get the response - * + * * @param {string} url URL * @param {string} data Attached data * @param {object} callback Callback function @@ -33,7 +33,7 @@ const wwa_ajax = function () { xmlHttpReq.send(data); xmlHttpReq.onreadystatechange = () => { if (xmlHttpReq.readyState === 4 && xmlHttpReq.status === 200) { - callback(xmlHttpReq.responseText, true); + callback(xmlHttpReq.responseText.trim(), true); } else if (xmlHttpReq.readyState === 4) { callback('Network Error.', false); } @@ -177,7 +177,7 @@ function wwa_auth() { alert(wwa_php_vars.i18n_31); return; } - let wwa_username = this.parentNode.previousElementSibling.previousElementSibling.getElementsByClassName('wwa-user-name')[0].value; + let wwa_username = this.closest('.wwa-login-form').getElementsByClassName('wwa-user-name')[0].value; if (wwa_username === '' && wwa_php_vars.usernameless !== 'true') { alert(wwa_php_vars.i18n_11); return; @@ -561,7 +561,7 @@ function updateList() { item_type_disabled = true; } } - htmlStr += `${item.name}${item.type === 'none' ? wwa_php_vars.i18n_24 : (item.type === 'platform' ? wwa_php_vars.i18n_25 : wwa_php_vars.i18n_26)}${item_type_disabled ? wwa_php_vars.i18n_35 : ''}${item.added}${item.last_used}${item.usernameless ? wwa_php_vars.i18n_1 + (wwa_php_vars.usernameless === 'true' ? '' : wwa_php_vars.i18n_9) : wwa_php_vars.i18n_8}${wwa_php_vars.i18n_20} | ${wwa_php_vars.i18n_27}`; + htmlStr += `${item.name}${item.type === 'none' ? wwa_php_vars.i18n_24 : (item.type === 'platform' ? wwa_php_vars.i18n_25 : wwa_php_vars.i18n_26)}${item_type_disabled ? wwa_php_vars.i18n_35 : ''}${item.added}${item.last_used}${item.usernameless ? wwa_php_vars.i18n_1 + (wwa_php_vars.usernameless === 'true' ? '' : wwa_php_vars.i18n_9) : wwa_php_vars.i18n_8}${wwa_php_vars.i18n_20} | ${wwa_php_vars.i18n_27}`; } wwa_dom('wwa-authenticator-list', (dom) => { dom.innerHTML = htmlStr }, 'class'); if (has_usernameless || wwa_php_vars.usernameless === 'true') { diff --git a/wp-content/plugins/wp-webauthn/js/login.js b/wp-content/plugins/wp-webauthn/js/login.js index 4a0c1284..bf69e7b4 100644 --- a/wp-content/plugins/wp-webauthn/js/login.js +++ b/wp-content/plugins/wp-webauthn/js/login.js @@ -15,7 +15,7 @@ const wwa_ajax = function () { xmlHttpReq.send(); xmlHttpReq.onreadystatechange = () => { if (xmlHttpReq.readyState === 4 && xmlHttpReq.status === 200) { - callback(xmlHttpReq.responseText, true); + callback(xmlHttpReq.responseText.trim(), true); } else if (xmlHttpReq.readyState === 4) { callback('Network Error.', false); } @@ -33,7 +33,7 @@ const wwa_ajax = function () { xmlHttpReq.send(data); xmlHttpReq.onreadystatechange = () => { if (xmlHttpReq.readyState === 4 && xmlHttpReq.status === 200) { - callback(xmlHttpReq.responseText, true); + callback(xmlHttpReq.responseText.trim(), true); } else if (xmlHttpReq.readyState === 4) { callback('Network Error.', false); } diff --git a/wp-content/plugins/wp-webauthn/js/profile.js b/wp-content/plugins/wp-webauthn/js/profile.js index 2673d0e0..7af900e0 100644 --- a/wp-content/plugins/wp-webauthn/js/profile.js +++ b/wp-content/plugins/wp-webauthn/js/profile.js @@ -59,7 +59,7 @@ function updateList() { item_type_disabled = true; } } - htmlStr += `${item.name}${item.type === 'none' ? php_vars.i18n_9 : (item.type === 'platform' ? php_vars.i18n_10 : php_vars.i18n_11)}${item_type_disabled ? php_vars.i18n_29 : ''}${item.added}${item.last_used}${item.usernameless ? php_vars.i18n_24 + (configs.usernameless === 'true' ? '' : php_vars.i18n_26) : php_vars.i18n_25}${php_vars.i18n_20} | ${php_vars.i18n_12}`; + htmlStr += `${item.name}${item.type === 'none' ? php_vars.i18n_9 : (item.type === 'platform' ? php_vars.i18n_10 : php_vars.i18n_11)}${item_type_disabled ? php_vars.i18n_29 : ''}${item.added}${item.last_used}${item.usernameless ? php_vars.i18n_24 + (configs.usernameless === 'true' ? '' : php_vars.i18n_26) : php_vars.i18n_25}${php_vars.i18n_20} | ${php_vars.i18n_12}`; } jQuery('#wwa-authenticator-list').html(htmlStr); if (has_usernameless || configs.usernameless === 'true') { @@ -247,7 +247,7 @@ jQuery('#wwa-bind').click((e) => { user_id: php_vars.user_id }, success: function (data) { - if (data === 'true') { + if (data.trim() === 'true') { // Registered jQuery('#wwa-show-progress').html(php_vars.i18n_3); jQuery('#wwa-bind').removeAttr('disabled'); @@ -382,7 +382,7 @@ jQuery('#wwa-test, #wwa-test_usernameless').click((e) => { user_id: php_vars.user_id }, success: function (data) { - if (data === 'true') { + if (data.trim() === 'true') { jQuery(tip_id).html(php_vars.i18n_16); jQuery('#wwa-test, #wwa-test_usernameless').removeAttr('disabled'); updateList(); diff --git a/wp-content/plugins/wp-webauthn/languages/template.pot b/wp-content/plugins/wp-webauthn/languages/template.pot index fa35e789..76ac8dc6 100644 --- a/wp-content/plugins/wp-webauthn/languages/template.pot +++ b/wp-content/plugins/wp-webauthn/languages/template.pot @@ -1,8 +1,8 @@ -# Copyright (C) 2023 Axton -# This file is distributed under the same license as the WP-WebAuthn plugin. +# Copyright (C) 2024 Axton +# This file is distributed under the GPLv3. msgid "" msgstr "" -"Project-Id-Version: WP-WebAuthn 1.3.1\n" +"Project-Id-Version: WP-WebAuthn 1.3.2\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wp-webauthn\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,22 +18,27 @@ msgstr "" "X-Domain: wp-webauthn\n" #. Plugin Name of the plugin +#: wp-webauthn.php msgid "WP-WebAuthn" msgstr "" #. Plugin URI of the plugin +#: wp-webauthn.php msgid "https://flyhigher.top" msgstr "" #. Description of the plugin +#: wp-webauthn.php msgid "WP-WebAuthn allows you to safely login to your WordPress site without password." msgstr "" #. Author of the plugin +#: wp-webauthn.php msgid "Axton" msgstr "" #. Author URI of the plugin +#: wp-webauthn.php msgid "https://axton.cc" msgstr "" @@ -42,7 +47,7 @@ msgid "User verification is disabled by default because some mobile devices do n msgstr "" #: wwa-admin-content.php:7 -#: wwa-admin-content.php:303 +#: wwa-admin-content.php:307 msgid "Log count: " msgstr "" @@ -68,198 +73,199 @@ msgstr "" msgid "WebAuthn features are restricted to websites in secure contexts. Please make sure your website is served over HTTPS or locally with localhost." msgstr "" -#: wwa-admin-content.php:127 +#: wwa-admin-content.php:131 msgid "Settings saved." msgstr "" -#: wwa-admin-content.php:129 +#: wwa-admin-content.php:133 msgid "Settings NOT saved." msgstr "" -#: wwa-admin-content.php:144 +#: wwa-admin-content.php:148 msgid "Preferred login method" msgstr "" -#: wwa-admin-content.php:148 +#: wwa-admin-content.php:152 msgid "Prefer WebAuthn" msgstr "" -#: wwa-admin-content.php:149 +#: wwa-admin-content.php:153 msgid "Prefer password" msgstr "" -#: wwa-admin-content.php:150 -#: wwa-profile-content.php:81 +#: wwa-admin-content.php:154 +#: wwa-profile-content.php:82 msgid "WebAuthn Only" msgstr "" -#: wwa-admin-content.php:152 +#: wwa-admin-content.php:156 msgid "When using \"WebAuthn Only\", password login will be completely disabled. Please make sure your browser supports WebAuthn, otherwise you may unable to login.
User that doesn't have any registered authenticator (e.g. new user) will unable to login when using \"WebAuthn Only\".
When the browser does not support WebAuthn, the login method will default to password if password login is not disabled." msgstr "" -#: wwa-admin-content.php:156 +#: wwa-admin-content.php:160 msgid "Website identifier" msgstr "" -#: wwa-admin-content.php:159 +#: wwa-admin-content.php:163 msgid "This identifier is for identification purpose only and DOES NOT affect the authentication process in anyway." msgstr "" -#: wwa-admin-content.php:163 +#: wwa-admin-content.php:167 msgid "Website domain" msgstr "" -#: wwa-admin-content.php:166 +#: wwa-admin-content.php:170 msgid "This field MUST be exactly the same with the current domain or parent domain." msgstr "" -#: wwa-admin-content.php:173 +#: wwa-admin-content.php:177 msgid "Allow to remember login" msgstr "" -#: wwa-admin-content.php:182 -#: wwa-admin-content.php:198 -#: wwa-admin-content.php:209 -#: wwa-admin-content.php:225 -#: wwa-admin-content.php:300 -#: wwa-profile-content.php:155 -#: wwa-shortcodes.php:118 +#: wwa-admin-content.php:186 +#: wwa-admin-content.php:202 +#: wwa-admin-content.php:213 +#: wwa-admin-content.php:229 +#: wwa-admin-content.php:304 +#: wwa-profile-content.php:157 +#: wwa-shortcodes.php:135 msgid "Enable" msgstr "" -#: wwa-admin-content.php:183 -#: wwa-admin-content.php:199 -#: wwa-admin-content.php:210 -#: wwa-admin-content.php:226 -#: wwa-admin-content.php:301 -#: wwa-profile-content.php:156 -#: wwa-shortcodes.php:118 +#: wwa-admin-content.php:187 +#: wwa-admin-content.php:203 +#: wwa-admin-content.php:214 +#: wwa-admin-content.php:230 +#: wwa-admin-content.php:305 +#: wwa-profile-content.php:158 +#: wwa-shortcodes.php:135 msgid "Disable" msgstr "" -#: wwa-admin-content.php:184 +#: wwa-admin-content.php:188 msgid "Show the 'Remember Me' checkbox beside the login form when using WebAuthn." msgstr "" -#: wwa-admin-content.php:189 +#: wwa-admin-content.php:193 msgid "Allow to login with email addresses" msgstr "" -#: wwa-admin-content.php:200 +#: wwa-admin-content.php:204 msgid "Allow to find users via email addresses when logging in.
Note that if enabled attackers may be able to brute force the correspondences between email addresses and users." msgstr "" -#: wwa-admin-content.php:205 +#: wwa-admin-content.php:209 msgid "Require user verification" msgstr "" -#: wwa-admin-content.php:211 +#: wwa-admin-content.php:215 msgid "User verification can improve security, but is not fully supported by mobile devices.
If you cannot register or verify your authenticators, please consider disabling user verification." msgstr "" -#: wwa-admin-content.php:216 +#: wwa-admin-content.php:220 msgid "Allow to login without username" msgstr "" -#: wwa-admin-content.php:227 +#: wwa-admin-content.php:231 msgid "Allow users to register authenticator with usernameless authentication feature and login without username.
User verification will be enabled automatically when authenticating with usernameless authentication feature.
Some authenticators and some browsers DO NOT support this feature." msgstr "" -#: wwa-admin-content.php:232 +#: wwa-admin-content.php:236 msgid "Allow a specific type of authenticator" msgstr "" -#: wwa-admin-content.php:241 +#: wwa-admin-content.php:245 #: wwa-profile-content.php:15 -#: wwa-profile-content.php:136 +#: wwa-profile-content.php:138 #: wwa-shortcodes.php:33 -#: wwa-shortcodes.php:118 +#: wwa-shortcodes.php:127 msgid "Any" msgstr "" -#: wwa-admin-content.php:242 +#: wwa-admin-content.php:246 msgid "Platform (e.g. Passkey or built-in sensors)" msgstr "" -#: wwa-admin-content.php:243 -#: wwa-profile-content.php:138 -#: wwa-shortcodes.php:118 +#: wwa-admin-content.php:247 +#: wwa-profile-content.php:140 +#: wwa-shortcodes.php:129 msgid "Roaming (e.g. USB security keys)" msgstr "" -#: wwa-admin-content.php:245 +#: wwa-admin-content.php:249 msgid "If a type is selected, the browser will only prompt for authenticators of selected type when authenticating and user can only register authenticators of selected type." msgstr "" -#: wwa-admin-content.php:252 +#: wwa-admin-content.php:256 msgid "Disable password reset for" msgstr "" -#: wwa-admin-content.php:261 +#: wwa-admin-content.php:265 msgid "Off" msgstr "" -#: wwa-admin-content.php:262 +#: wwa-admin-content.php:266 msgid "Everyone except administrators" msgstr "" -#: wwa-admin-content.php:263 +#: wwa-admin-content.php:267 msgid "Everyone" msgstr "" -#: wwa-admin-content.php:265 +#: wwa-admin-content.php:269 msgid "Disable the \"Set new password\" and \"Forgot password\" features, and remove the \"Forgot password\" link on the login page. This may be useful when enabling \"WebAuthn Only\".
If \"Everyone except administrators\" is selected, only administrators with the \"Edit user\" permission will be able to update passwords (for all users)." msgstr "" -#: wwa-admin-content.php:272 +#: wwa-admin-content.php:276 msgid "After User Registration" msgstr "" -#: wwa-admin-content.php:281 +#: wwa-admin-content.php:285 msgid "No action" msgstr "" -#: wwa-admin-content.php:282 +#: wwa-admin-content.php:286 msgid "Log user in and redirect to user's profile" msgstr "" -#: wwa-admin-content.php:284 +#: wwa-admin-content.php:288 msgid "What to do when a new user registered.
By default, new users have to login manually after registration. If \"WebAuthn Only\" is enabled, they will not be able to login.
When using \"Log user in\", new users will be logged in automatically and redirected to their profile settings so that they can set up WebAuthn authenticators." msgstr "" -#: wwa-admin-content.php:291 +#: wwa-admin-content.php:295 msgid "Logging" msgstr "" -#: wwa-admin-content.php:303 +#: wwa-admin-content.php:307 msgid "Clear log" msgstr "" -#: wwa-admin-content.php:305 +#: wwa-admin-content.php:309 msgid "For debugging only. Enable only when needed.
Note: Logs may contain sensitive information." msgstr "" -#: wwa-admin-content.php:314 +#: wwa-admin-content.php:318 msgid "Log" msgstr "" -#: wwa-admin-content.php:316 +#: wwa-admin-content.php:320 msgid "Automatic update every 5 seconds." msgstr "" -#: wwa-admin-content.php:320 +#. translators: %s: admin profile url +#: wwa-admin-content.php:325 msgid "To register a new authenticator or edit your authenticators, please go to your profile." msgstr "" #: wwa-functions.php:159 -#: wwa-shortcodes.php:88 +#: wwa-shortcodes.php:91 msgid "Auth" msgstr "" #: wwa-functions.php:160 #: wwa-shortcodes.php:11 -#: wwa-shortcodes.php:85 -#: wwa-shortcodes.php:88 +#: wwa-shortcodes.php:81 +#: wwa-shortcodes.php:90 msgid "Authenticate with WebAuthn" msgstr "" @@ -293,7 +299,7 @@ msgid "It looks like your browser doesn't support WebAuthn, which means you may msgstr "" #: wwa-functions.php:167 -#: wwa-shortcodes.php:88 +#: wwa-shortcodes.php:87 msgid "Username" msgstr "" @@ -314,36 +320,42 @@ msgstr "" msgid "Logging in with password has been disabled for this account." msgstr "" -#: wwa-functions.php:275 +#. translators: %s: 'the site' or 'your account', and admin profile url +#: wwa-functions.php:276 msgid "Logging in with password has been disabled for %s but you haven't register any WebAuthn authenticator yet. You may unable to login again once you log out. Register" msgstr "" -#: wwa-functions.php:275 -#: wwa-functions.php:320 +#. translators: %s: 'the site' or 'your account', and admin profile url +#. translators: %s: 'the site' or 'your account' +#: wwa-functions.php:276 +#: wwa-functions.php:322 msgid "the site" msgstr "" -#: wwa-functions.php:275 +#. translators: %s: 'the site' or 'your account', and admin profile url +#: wwa-functions.php:276 msgid "your account" msgstr "" -#: wwa-functions.php:320 +#. translators: %s: 'the site' or 'your account' +#: wwa-functions.php:322 msgid "Logging in with password has been disabled for %s but this account haven't register any WebAuthn authenticator yet. This user may unable to login." msgstr "" -#: wwa-functions.php:320 +#. translators: %s: 'the site' or 'your account' +#: wwa-functions.php:322 msgid "this account" msgstr "" -#: wwa-functions.php:348 +#: wwa-functions.php:350 msgid "Settings" msgstr "" -#: wwa-functions.php:356 +#: wwa-functions.php:358 msgid "GitHub" msgstr "" -#: wwa-functions.php:357 +#: wwa-functions.php:359 msgid "Documentation" msgstr "" @@ -487,139 +499,142 @@ msgstr "" msgid "The site administrator only allow roaming authenticators currently." msgstr "" -#: wwa-profile-content.php:63 +#: wwa-profile-content.php:64 msgid "You've successfully registered! Now you can register your authenticators below." msgstr "" -#: wwa-profile-content.php:75 +#: wwa-profile-content.php:76 msgid "This site is not correctly configured to use WebAuthn. Please contact the site administrator." msgstr "" -#: wwa-profile-content.php:85 +#: wwa-profile-content.php:86 msgid "Disable password login for this account" msgstr "" -#: wwa-profile-content.php:87 +#: wwa-profile-content.php:88 msgid "When checked, password login will be completely disabled. Please make sure your browser supports WebAuthn and you have a registered authenticator, otherwise you may unable to login." msgstr "" -#: wwa-profile-content.php:87 +#: wwa-profile-content.php:88 msgid "The site administrator has disabled password login for the whole site." msgstr "" -#: wwa-profile-content.php:91 +#: wwa-profile-content.php:92 msgid "Registered WebAuthn Authenticators" msgstr "" -#: wwa-profile-content.php:96 -#: wwa-profile-content.php:111 -#: wwa-shortcodes.php:156 -#: wwa-shortcodes.php:158 -msgid "Identifier" -msgstr "" - #: wwa-profile-content.php:97 #: wwa-profile-content.php:112 -#: wwa-shortcodes.php:156 -#: wwa-shortcodes.php:158 -msgid "Type" +#: wwa-shortcodes.php:175 +#: wwa-shortcodes.php:177 +msgid "Identifier" msgstr "" #: wwa-profile-content.php:98 #: wwa-profile-content.php:113 -#: wwa-shortcodes.php:156 -#: wwa-shortcodes.php:158 -msgctxt "time" -msgid "Registered" +#: wwa-shortcodes.php:175 +#: wwa-shortcodes.php:177 +msgid "Type" msgstr "" #: wwa-profile-content.php:99 #: wwa-profile-content.php:114 -msgid "Last used" +#: wwa-shortcodes.php:175 +#: wwa-shortcodes.php:177 +msgctxt "time" +msgid "Registered" msgstr "" #: wwa-profile-content.php:100 #: wwa-profile-content.php:115 -#: wwa-shortcodes.php:156 -#: wwa-shortcodes.php:158 -msgid "Usernameless" +#: wwa-shortcodes.php:175 +#: wwa-shortcodes.php:177 +msgid "Last used" msgstr "" #: wwa-profile-content.php:101 #: wwa-profile-content.php:116 -#: wwa-shortcodes.php:156 -#: wwa-shortcodes.php:158 +#: wwa-shortcodes.php:175 +#: wwa-shortcodes.php:177 +msgid "Usernameless" +msgstr "" + +#: wwa-profile-content.php:102 +#: wwa-profile-content.php:117 +#: wwa-shortcodes.php:175 +#: wwa-shortcodes.php:177 msgid "Action" msgstr "" -#: wwa-profile-content.php:106 -#: wwa-shortcodes.php:157 +#: wwa-profile-content.php:107 +#: wwa-shortcodes.php:176 msgid "Loading..." msgstr "" -#: wwa-profile-content.php:123 -#: wwa-profile-content.php:126 +#: wwa-profile-content.php:124 +#: wwa-profile-content.php:127 msgid "Register New Authenticator" msgstr "" -#: wwa-profile-content.php:123 -#: wwa-profile-content.php:167 +#: wwa-profile-content.php:124 +#: wwa-profile-content.php:169 msgid "Verify Authenticator" msgstr "" -#: wwa-profile-content.php:127 +#. translators: %s: user login name +#: wwa-profile-content.php:129 msgid "You are about to associate an authenticator with the current account %s.
You can register multiple authenticators for an account." msgstr "" -#: wwa-profile-content.php:130 -#: wwa-shortcodes.php:118 +#: wwa-profile-content.php:132 +#: wwa-shortcodes.php:125 msgid "Type of authenticator" msgstr "" -#: wwa-profile-content.php:137 -#: wwa-shortcodes.php:118 +#: wwa-profile-content.php:139 +#: wwa-shortcodes.php:128 msgid "Platform (e.g. built-in fingerprint sensors)" msgstr "" -#: wwa-profile-content.php:140 -#: wwa-shortcodes.php:118 +#: wwa-profile-content.php:142 +#: wwa-shortcodes.php:131 msgid "If a type is selected, the browser will only prompt for authenticators of selected type.
Regardless of the type, you can only log in with the very same authenticators you've registered." msgstr "" -#: wwa-profile-content.php:144 +#: wwa-profile-content.php:146 msgid "Authenticator Identifier" msgstr "" -#: wwa-profile-content.php:147 -#: wwa-shortcodes.php:118 +#: wwa-profile-content.php:149 +#: wwa-shortcodes.php:134 msgid "An easily identifiable name for the authenticator. DOES NOT affect the authentication process in anyway." msgstr "" -#: wwa-profile-content.php:152 -#: wwa-shortcodes.php:118 +#: wwa-profile-content.php:154 +#: wwa-shortcodes.php:135 msgid "Login without username" msgstr "" -#: wwa-profile-content.php:157 -#: wwa-shortcodes.php:118 +#: wwa-profile-content.php:159 +#: wwa-shortcodes.php:135 msgid "If registered authenticator with this feature, you can login without enter your username.
Some authenticators like U2F-only authenticators and some browsers DO NOT support this feature.
A record will be stored in the authenticator permanently untill you reset it." msgstr "" -#: wwa-profile-content.php:163 +#: wwa-profile-content.php:165 msgid "Start Registration" msgstr "" -#: wwa-profile-content.php:168 +#: wwa-profile-content.php:170 msgid "Click Test Login to verify that the registered authenticators are working." msgstr "" -#: wwa-profile-content.php:169 -#: wwa-shortcodes.php:144 +#: wwa-profile-content.php:171 +#: wwa-shortcodes.php:163 msgid "Test Login" msgstr "" -#: wwa-profile-content.php:171 -#: wwa-shortcodes.php:144 +#: wwa-profile-content.php:173 +#: wwa-shortcodes.php:163 msgid "Test Login (usernameless)" msgstr "" @@ -627,20 +642,20 @@ msgstr "" msgid "Error: The username field is empty." msgstr "" -#: wwa-shortcodes.php:88 +#: wwa-shortcodes.php:91 msgid "Authenticate with password" msgstr "" -#: wwa-shortcodes.php:105 -#: wwa-shortcodes.php:133 -#: wwa-shortcodes.php:166 +#: wwa-shortcodes.php:110 +#: wwa-shortcodes.php:152 +#: wwa-shortcodes.php:185 msgid "You haven't logged in yet." msgstr "" -#: wwa-shortcodes.php:118 +#: wwa-shortcodes.php:132 msgid "Authenticator identifier" msgstr "" -#: wwa-shortcodes.php:118 +#: wwa-shortcodes.php:136 msgid "Start registration" msgstr "" diff --git a/wp-content/plugins/wp-webauthn/readme.txt b/wp-content/plugins/wp-webauthn/readme.txt index 43c1973a..d58fe3a0 100644 --- a/wp-content/plugins/wp-webauthn/readme.txt +++ b/wp-content/plugins/wp-webauthn/readme.txt @@ -1,10 +1,10 @@ === WP-WebAuthn === Contributors: axton Donate link: https://flyhigher.top/about -Tags: u2f, fido, fido2, webauthn, passkey, login, security, password, authentication +Tags: u2f, webauthn, passkey, login, security Requires at least: 5.0 -Tested up to: 6.3 -Stable tag: 1.3.1 +Tested up to: 6.6 +Stable tag: 1.3.4 Requires PHP: 7.2 License: GPLv3 License URI: https://www.gnu.org/licenses/gpl-3.0.html @@ -80,6 +80,19 @@ To use FaceID or TouchID, you need to use iOS/iPadOS 14+. == Changelog == += 1.3.4 = +Fix: Make sure AJAX works with extra spaces/new lines +Note: We'll soon drop support for PHP 7.4 and below. Please upgrade your PHP version to 8.0+. + += 1.3.3 = +Fix: Support for PHP 7.2+ + += 1.3.2 = +Fix: XSS issues in login form shortcode +Fix: Wrong user variable check (thanks to bfren) +Fix: Javascript error in login form shortcode (thanks to David Stone) +Fix: Javascript error with certain authenticator names in authenticator list tables + = 1.3.1 = Update: Translations diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/autoload.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/autoload.php index 5da3be60..710379cf 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/autoload.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/autoload.php @@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) { require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit09e765e3690d5165ed98a315471eec7d::getLoader(); +return ComposerAutoloaderInite99fdfd0dbb5e609b534e430fe6b54ef::getLoader(); diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/composer/autoload_classmap.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/composer/autoload_classmap.php index 10611bf5..6e27618d 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/composer/autoload_classmap.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/composer/autoload_classmap.php @@ -91,6 +91,7 @@ return array( 'CBOR\\TextStringWithChunkObject' => $vendorDir . '/spomky-labs/cbor-php/src/TextStringWithChunkObject.php', 'CBOR\\UnsignedIntegerObject' => $vendorDir . '/spomky-labs/cbor-php/src/UnsignedIntegerObject.php', 'CBOR\\Utils' => $vendorDir . '/spomky-labs/cbor-php/src/Utils.php', + 'CURLStringFile' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php', 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', 'Cose\\Algorithm\\Algorithm' => $vendorDir . '/web-auth/cose-lib/src/Algorithm/Algorithm.php', 'Cose\\Algorithm\\Mac\\HS256' => $vendorDir . '/web-auth/cose-lib/src/Algorithm/Mac/HS256.php', diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/composer/autoload_real.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/composer/autoload_real.php index fb9505bb..c22d6f12 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/composer/autoload_real.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit09e765e3690d5165ed98a315471eec7d +class ComposerAutoloaderInite99fdfd0dbb5e609b534e430fe6b54ef { private static $loader; @@ -22,16 +22,16 @@ class ComposerAutoloaderInit09e765e3690d5165ed98a315471eec7d return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit09e765e3690d5165ed98a315471eec7d', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInite99fdfd0dbb5e609b534e430fe6b54ef', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); - spl_autoload_unregister(array('ComposerAutoloaderInit09e765e3690d5165ed98a315471eec7d', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInite99fdfd0dbb5e609b534e430fe6b54ef', 'loadClassLoader')); require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit09e765e3690d5165ed98a315471eec7d::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInite99fdfd0dbb5e609b534e430fe6b54ef::getInitializer($loader)); $loader->register(true); - $filesToLoad = \Composer\Autoload\ComposerStaticInit09e765e3690d5165ed98a315471eec7d::$files; + $filesToLoad = \Composer\Autoload\ComposerStaticInite99fdfd0dbb5e609b534e430fe6b54ef::$files; $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/composer/autoload_static.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/composer/autoload_static.php index eb725853..618b51a1 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/composer/autoload_static.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit09e765e3690d5165ed98a315471eec7d +class ComposerStaticInite99fdfd0dbb5e609b534e430fe6b54ef { public static $files = array ( 'a4ecaeafb8cfb009ad0e052c90355e98' => __DIR__ . '/..' . '/beberlei/assert/lib/Assert/functions.php', @@ -359,6 +359,7 @@ class ComposerStaticInit09e765e3690d5165ed98a315471eec7d 'CBOR\\TextStringWithChunkObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/TextStringWithChunkObject.php', 'CBOR\\UnsignedIntegerObject' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/UnsignedIntegerObject.php', 'CBOR\\Utils' => __DIR__ . '/..' . '/spomky-labs/cbor-php/src/Utils.php', + 'CURLStringFile' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php', 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 'Cose\\Algorithm\\Algorithm' => __DIR__ . '/..' . '/web-auth/cose-lib/src/Algorithm/Algorithm.php', 'Cose\\Algorithm\\Mac\\HS256' => __DIR__ . '/..' . '/web-auth/cose-lib/src/Algorithm/Mac/HS256.php', @@ -939,9 +940,9 @@ class ComposerStaticInit09e765e3690d5165ed98a315471eec7d public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit09e765e3690d5165ed98a315471eec7d::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit09e765e3690d5165ed98a315471eec7d::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit09e765e3690d5165ed98a315471eec7d::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInite99fdfd0dbb5e609b534e430fe6b54ef::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInite99fdfd0dbb5e609b534e430fe6b54ef::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInite99fdfd0dbb5e609b534e430fe6b54ef::$classMap; }, null, ClassLoader::class); } diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/composer/installed.json b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/composer/installed.json index 19e503fa..9a36beca 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/composer/installed.json +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/composer/installed.json @@ -232,17 +232,17 @@ }, { "name": "league/uri", - "version": "6.7.2", - "version_normalized": "6.7.2.0", + "version": "6.8.0", + "version_normalized": "6.8.0.0", "source": { "type": "git", "url": "https://github.com/thephpleague/uri.git", - "reference": "d3b50812dd51f3fbf176344cc2981db03d10fe06" + "reference": "a700b4656e4c54371b799ac61e300ab25a2d1d39" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/d3b50812dd51f3fbf176344cc2981db03d10fe06", - "reference": "d3b50812dd51f3fbf176344cc2981db03d10fe06", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/a700b4656e4c54371b799ac61e300ab25a2d1d39", + "reference": "a700b4656e4c54371b799ac61e300ab25a2d1d39", "shasum": "", "mirrors": [ { @@ -254,22 +254,23 @@ "require": { "ext-json": "*", "league/uri-interfaces": "^2.3", - "php": "^7.4 || ^8.0", - "psr/http-message": "^1.0" + "php": "^8.1", + "psr/http-message": "^1.0.1" }, "conflict": { "league/uri-schemes": "^1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^v3.3.2", - "nyholm/psr7": "^1.5", - "php-http/psr7-integration-tests": "^1.1", - "phpstan/phpstan": "^1.2.0", + "friendsofphp/php-cs-fixer": "^v3.9.5", + "nyholm/psr7": "^1.5.1", + "php-http/psr7-integration-tests": "^1.1.1", + "phpbench/phpbench": "^1.2.6", + "phpstan/phpstan": "^1.8.5", "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-phpunit": "^1.0.0", - "phpstan/phpstan-strict-rules": "^1.1.0", - "phpunit/phpunit": "^9.5.10", - "psr/http-factory": "^1.0" + "phpstan/phpstan-phpunit": "^1.1.1", + "phpstan/phpstan-strict-rules": "^1.4.3", + "phpunit/phpunit": "^9.5.24", + "psr/http-factory": "^1.0.1" }, "suggest": { "ext-fileinfo": "Needed to create Data URI from a filepath", @@ -277,7 +278,7 @@ "league/uri-components": "Needed to easily manipulate URI objects", "psr/http-factory": "Needed to use the URI factory" }, - "time": "2022-09-13T19:50:42+00:00", + "time": "2022-09-13T19:58:47+00:00", "type": "library", "extra": { "branch-alias": { @@ -328,7 +329,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri/issues", - "source": "https://github.com/thephpleague/uri/tree/6.7.2" + "source": "https://github.com/thephpleague/uri/tree/6.8.0" }, "funding": [ { @@ -420,17 +421,17 @@ }, { "name": "nyholm/psr7", - "version": "1.8.0", - "version_normalized": "1.8.0.0", + "version": "1.8.2", + "version_normalized": "1.8.2.0", "source": { "type": "git", "url": "https://github.com/Nyholm/psr7.git", - "reference": "3cb4d163b58589e47b35103e8e5e6a6a475b47be" + "reference": "a71f2b11690f4b24d099d6b16690a90ae14fc6f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Nyholm/psr7/zipball/3cb4d163b58589e47b35103e8e5e6a6a475b47be", - "reference": "3cb4d163b58589e47b35103e8e5e6a6a475b47be", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/a71f2b11690f4b24d099d6b16690a90ae14fc6f3", + "reference": "a71f2b11690f4b24d099d6b16690a90ae14fc6f3", "shasum": "", "mirrors": [ { @@ -456,7 +457,7 @@ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.4", "symfony/error-handler": "^4.4" }, - "time": "2023-05-02T11:26:24+00:00", + "time": "2024-09-09T07:06:30+00:00", "type": "library", "extra": { "branch-alias": { @@ -491,7 +492,7 @@ ], "support": { "issues": "https://github.com/Nyholm/psr7/issues", - "source": "https://github.com/Nyholm/psr7/tree/1.8.0" + "source": "https://github.com/Nyholm/psr7/tree/1.8.2" }, "funding": [ { @@ -582,17 +583,17 @@ }, { "name": "psr/http-client", - "version": "1.0.1", - "version_normalized": "1.0.1.0", + "version": "1.0.3", + "version_normalized": "1.0.3.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-client.git", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", "shasum": "", "mirrors": [ { @@ -603,9 +604,9 @@ }, "require": { "php": "^7.0 || ^8.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0 || ^2.0" }, - "time": "2020-06-29T06:28:15+00:00", + "time": "2023-09-23T14:17:50+00:00", "type": "library", "extra": { "branch-alias": { @@ -625,7 +626,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for HTTP clients", @@ -637,7 +638,7 @@ "psr-18" ], "support": { - "source": "https://github.com/php-fig/http-client/tree/master" + "source": "https://github.com/php-fig/http-client" }, "install-path": "../psr/http-client" }, @@ -1197,17 +1198,17 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.27.0", - "version_normalized": "1.27.0.0", + "version": "v1.31.0", + "version_normalized": "1.31.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "", "mirrors": [ { @@ -1217,7 +1218,7 @@ ] }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" @@ -1225,12 +1226,9 @@ "suggest": { "ext-ctype": "For best performance" }, - "time": "2022-11-03T14:55:06+00:00", + "time": "2024-09-09T11:45:10+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -1268,7 +1266,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" }, "funding": [ { @@ -1288,17 +1286,17 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.27.0", - "version_normalized": "1.27.0.0", + "version": "v1.31.0", + "version_normalized": "1.31.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", "shasum": "", "mirrors": [ { @@ -1308,14 +1306,11 @@ ] }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, - "time": "2022-11-03T14:55:06+00:00", + "time": "2024-09-09T11:45:10+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -1360,7 +1355,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" }, "funding": [ { @@ -1380,17 +1375,17 @@ }, { "name": "symfony/polyfill-php81", - "version": "v1.27.0", - "version_normalized": "1.27.0.0", + "version": "v1.30.0", + "version_normalized": "1.30.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a" + "reference": "3fb075789fb91f9ad9af537c4012d523085bd5af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/707403074c8ea6e2edaf8794b0157a0bfa52157a", - "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/3fb075789fb91f9ad9af537c4012d523085bd5af", + "reference": "3fb075789fb91f9ad9af537c4012d523085bd5af", "shasum": "", "mirrors": [ { @@ -1402,12 +1397,9 @@ "require": { "php": ">=7.1" }, - "time": "2022-11-03T14:55:06+00:00", + "time": "2024-06-19T12:30:46+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -1448,7 +1440,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.30.0" }, "funding": [ { @@ -1468,17 +1460,17 @@ }, { "name": "symfony/process", - "version": "v5.4.28", - "version_normalized": "5.4.28.0", + "version": "v5.4.40", + "version_normalized": "5.4.40.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "45261e1fccad1b5447a8d7a8e67aa7b4a9798b7b" + "reference": "deedcb3bb4669cae2148bc920eafd2b16dc7c046" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/45261e1fccad1b5447a8d7a8e67aa7b4a9798b7b", - "reference": "45261e1fccad1b5447a8d7a8e67aa7b4a9798b7b", + "url": "https://api.github.com/repos/symfony/process/zipball/deedcb3bb4669cae2148bc920eafd2b16dc7c046", + "reference": "deedcb3bb4669cae2148bc920eafd2b16dc7c046", "shasum": "", "mirrors": [ { @@ -1491,7 +1483,7 @@ "php": ">=7.2.5", "symfony/polyfill-php80": "^1.16" }, - "time": "2023-08-07T10:36:04+00:00", + "time": "2024-05-31T14:33:22+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -1519,7 +1511,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.28" + "source": "https://github.com/symfony/process/tree/v5.4.40" }, "funding": [ { @@ -2009,6 +2001,7 @@ "type": "patreon" } ], + "abandoned": "web-token/jwt-library", "install-path": "../web-token/jwt-core" }, { @@ -2095,6 +2088,7 @@ "type": "patreon" } ], + "abandoned": "web-token/jwt-library", "install-path": "../web-token/jwt-key-mgmt" }, { @@ -2180,6 +2174,7 @@ "type": "patreon" } ], + "abandoned": "web-token/jwt-library", "install-path": "../web-token/jwt-signature" }, { @@ -2258,6 +2253,7 @@ "type": "patreon" } ], + "abandoned": "web-token/jwt-library", "install-path": "../web-token/jwt-signature-algorithm-ecdsa" }, { @@ -2336,6 +2332,7 @@ "type": "patreon" } ], + "abandoned": "web-token/jwt-library", "install-path": "../web-token/jwt-signature-algorithm-eddsa" }, { @@ -2419,6 +2416,7 @@ "type": "patreon" } ], + "abandoned": "web-token/jwt-library", "install-path": "../web-token/jwt-signature-algorithm-rsa" } ], diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/composer/installed.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/composer/installed.php index 0363ba44..f66df5e4 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/composer/installed.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/composer/installed.php @@ -1,9 +1,9 @@ array( 'name' => '__root__', - 'pretty_version' => '1.3.1', - 'version' => '1.3.1.0', - 'reference' => '7ba904e1020a15ea593301b05ecfc4d74aa61570', + 'pretty_version' => '1.3.4', + 'version' => '1.3.4.0', + 'reference' => '88207a7a7032f209d572a80f06699769886cdeb3', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -11,9 +11,9 @@ ), 'versions' => array( '__root__' => array( - 'pretty_version' => '1.3.1', - 'version' => '1.3.1.0', - 'reference' => '7ba904e1020a15ea593301b05ecfc4d74aa61570', + 'pretty_version' => '1.3.4', + 'version' => '1.3.4.0', + 'reference' => '88207a7a7032f209d572a80f06699769886cdeb3', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -47,9 +47,9 @@ 'dev_requirement' => false, ), 'league/uri' => array( - 'pretty_version' => '6.7.2', - 'version' => '6.7.2.0', - 'reference' => 'd3b50812dd51f3fbf176344cc2981db03d10fe06', + 'pretty_version' => '6.8.0', + 'version' => '6.8.0.0', + 'reference' => 'a700b4656e4c54371b799ac61e300ab25a2d1d39', 'type' => 'library', 'install_path' => __DIR__ . '/../league/uri', 'aliases' => array(), @@ -65,9 +65,9 @@ 'dev_requirement' => false, ), 'nyholm/psr7' => array( - 'pretty_version' => '1.8.0', - 'version' => '1.8.0.0', - 'reference' => '3cb4d163b58589e47b35103e8e5e6a6a475b47be', + 'pretty_version' => '1.8.2', + 'version' => '1.8.2.0', + 'reference' => 'a71f2b11690f4b24d099d6b16690a90ae14fc6f3', 'type' => 'library', 'install_path' => __DIR__ . '/../nyholm/psr7', 'aliases' => array(), @@ -89,9 +89,9 @@ ), ), 'psr/http-client' => array( - 'pretty_version' => '1.0.1', - 'version' => '1.0.1.0', - 'reference' => '2dfb5f6c5eff0e91e20e913f8c5452ed95b86621', + 'pretty_version' => '1.0.3', + 'version' => '1.0.3.0', + 'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/http-client', 'aliases' => array(), @@ -179,36 +179,36 @@ 'dev_requirement' => false, ), 'symfony/polyfill-ctype' => array( - 'pretty_version' => 'v1.27.0', - 'version' => '1.27.0.0', - 'reference' => '5bbc823adecdae860bb64756d639ecfec17b050a', + 'pretty_version' => 'v1.31.0', + 'version' => '1.31.0.0', + 'reference' => 'a3cc8b044a6ea513310cbd48ef7333b384945638', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-ctype', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/polyfill-php80' => array( - 'pretty_version' => 'v1.27.0', - 'version' => '1.27.0.0', - 'reference' => '7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936', + 'pretty_version' => 'v1.31.0', + 'version' => '1.31.0.0', + 'reference' => '60328e362d4c2c802a54fcbf04f9d3fb892b4cf8', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php80', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/polyfill-php81' => array( - 'pretty_version' => 'v1.27.0', - 'version' => '1.27.0.0', - 'reference' => '707403074c8ea6e2edaf8794b0157a0bfa52157a', + 'pretty_version' => 'v1.30.0', + 'version' => '1.30.0.0', + 'reference' => '3fb075789fb91f9ad9af537c4012d523085bd5af', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php81', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/process' => array( - 'pretty_version' => 'v5.4.28', - 'version' => '5.4.28.0', - 'reference' => '45261e1fccad1b5447a8d7a8e67aa7b4a9798b7b', + 'pretty_version' => 'v5.4.40', + 'version' => '5.4.40.0', + 'reference' => 'deedcb3bb4669cae2148bc920eafd2b16dc7c046', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/process', 'aliases' => array(), diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/composer.json b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/composer.json index 28edbd84..dd607231 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/composer.json +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/composer.json @@ -44,21 +44,22 @@ } ], "require": { - "php": "^7.4 || ^8.0", + "php": "^8.1", "ext-json": "*", - "psr/http-message": "^1.0", + "psr/http-message": "^1.0.1", "league/uri-interfaces": "^2.3" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^v3.3.2", - "nyholm/psr7": "^1.5", - "php-http/psr7-integration-tests": "^1.1", - "phpstan/phpstan": "^1.2.0", + "friendsofphp/php-cs-fixer": "^v3.9.5", + "nyholm/psr7": "^1.5.1", + "php-http/psr7-integration-tests": "^1.1.1", + "phpbench/phpbench": "^1.2.6", + "phpstan/phpstan": "^1.8.5", "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-phpunit": "^1.0.0", - "phpstan/phpstan-strict-rules": "^1.1.0", - "phpunit/phpunit": "^9.5.10", - "psr/http-factory": "^1.0" + "phpstan/phpstan-phpunit": "^1.1.1", + "phpstan/phpstan-strict-rules": "^1.4.3", + "phpunit/phpunit": "^9.5.24", + "psr/http-factory": "^1.0.1" }, "autoload": { "psr-4": { @@ -74,6 +75,7 @@ "league/uri-schemes": "^1.0" }, "scripts": { + "benchmark": "phpbench run src --report=default", "phpcs": "php-cs-fixer fix -v --diff --dry-run --allow-risky=yes --ansi", "phpcs:fix": "php-cs-fixer fix -vvv --allow-risky=yes --ansi", "phpstan": "phpstan analyse -l max -c phpstan.neon src --ansi --memory-limit=256M", diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/Http.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/Http.php index b3b8cea8..49551ae9 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/Http.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/Http.php @@ -17,19 +17,14 @@ use JsonSerializable; use League\Uri\Contracts\UriInterface; use League\Uri\Exceptions\SyntaxError; use Psr\Http\Message\UriInterface as Psr7UriInterface; -use function is_object; +use Stringable; use function is_scalar; -use function method_exists; -use function sprintf; final class Http implements Psr7UriInterface, JsonSerializable { - private UriInterface $uri; - - private function __construct(UriInterface $uri) + private function __construct(private readonly UriInterface $uri) { - $this->validate($uri); - $this->uri = $uri; + $this->validate($this->uri); } /** @@ -39,19 +34,18 @@ final class Http implements Psr7UriInterface, JsonSerializable */ private function validate(UriInterface $uri): void { - $scheme = $uri->getScheme(); - if (null === $scheme && '' === $uri->getHost()) { - throw new SyntaxError(sprintf('an URI without scheme can not contains a empty host string according to PSR-7: %s', (string) $uri)); + if (null === $uri->getScheme() && '' === $uri->getHost()) { + throw new SyntaxError('An URI without scheme can not contains a empty host string according to PSR-7: '.$uri); } $port = $uri->getPort(); if (null !== $port && ($port < 0 || $port > 65535)) { - throw new SyntaxError(sprintf('The URI port is outside the established TCP and UDP port ranges: %s', (string) $uri->getPort())); + throw new SyntaxError('The URI port is outside the established TCP and UDP port ranges: '.$uri); } } /** - * Static method called by PHP's var export. + * @param array{uri:UriInterface} $components */ public static function __set_state(array $components): self { @@ -60,10 +54,8 @@ final class Http implements Psr7UriInterface, JsonSerializable /** * Create a new instance from a string. - * - * @param string|mixed $uri */ - public static function createFromString($uri = ''): self + public static function createFromString(Stringable|UriInterface|String $uri = ''): self { return new self(Uri::createFromString($uri)); } @@ -91,21 +83,18 @@ final class Http implements Psr7UriInterface, JsonSerializable * Create a new instance from a URI and a Base URI. * * The returned URI must be absolute. - * - * @param mixed $uri the input URI to create - * @param mixed $base_uri the base URI used for reference */ - public static function createFromBaseUri($uri, $base_uri = null): self - { + public static function createFromBaseUri( + Stringable|UriInterface|String $uri, + Stringable|UriInterface|String $base_uri = null + ): self { return new self(Uri::createFromBaseUri($uri, $base_uri)); } /** * Create a new instance from a URI object. - * - * @param Psr7UriInterface|UriInterface $uri the input URI to create */ - public static function createFromUri($uri): self + public static function createFromUri(Psr7UriInterface|UriInterface $uri): self { if ($uri instanceof UriInterface) { return new self($uri); @@ -178,145 +167,6 @@ final class Http implements Psr7UriInterface, JsonSerializable return (string) $this->uri->getFragment(); } - /** - * {@inheritDoc} - */ - public function withScheme($scheme): self - { - /** @var string $scheme */ - $scheme = $this->filterInput($scheme); - if ('' === $scheme) { - $scheme = null; - } - - $uri = $this->uri->withScheme($scheme); - if ((string) $uri === (string) $this->uri) { - return $this; - } - - return new self($uri); - } - - /** - * Safely stringify input when possible. - * - * @param mixed $str the value to evaluate as a string - * - * @throws SyntaxError if the submitted data can not be converted to string - * - * @return string|mixed - */ - private function filterInput($str) - { - if (is_scalar($str) || (is_object($str) && method_exists($str, '__toString'))) { - return (string) $str; - } - - return $str; - } - - /** - * {@inheritDoc} - */ - public function withUserInfo($user, $password = null): self - { - /** @var string $user */ - $user = $this->filterInput($user); - if ('' === $user) { - $user = null; - } - - $uri = $this->uri->withUserInfo($user, $password); - if ((string) $uri === (string) $this->uri) { - return $this; - } - - return new self($uri); - } - - /** - * {@inheritDoc} - */ - public function withHost($host): self - { - /** @var string $host */ - $host = $this->filterInput($host); - if ('' === $host) { - $host = null; - } - - $uri = $this->uri->withHost($host); - if ((string) $uri === (string) $this->uri) { - return $this; - } - - return new self($uri); - } - - /** - * {@inheritDoc} - */ - public function withPort($port): self - { - $uri = $this->uri->withPort($port); - if ((string) $uri === (string) $this->uri) { - return $this; - } - - return new self($uri); - } - - /** - * {@inheritDoc} - */ - public function withPath($path): self - { - $uri = $this->uri->withPath($path); - if ((string) $uri === (string) $this->uri) { - return $this; - } - - return new self($uri); - } - - /** - * {@inheritDoc} - */ - public function withQuery($query): self - { - /** @var string $query */ - $query = $this->filterInput($query); - if ('' === $query) { - $query = null; - } - - $uri = $this->uri->withQuery($query); - if ((string) $uri === (string) $this->uri) { - return $this; - } - - return new self($uri); - } - - /** - * {@inheritDoc} - */ - public function withFragment($fragment): self - { - /** @var string $fragment */ - $fragment = $this->filterInput($fragment); - if ('' === $fragment) { - $fragment = null; - } - - $uri = $this->uri->withFragment($fragment); - if ((string) $uri === (string) $this->uri) { - return $this; - } - - return new self($uri); - } - /** * {@inheritDoc} */ @@ -332,4 +182,88 @@ final class Http implements Psr7UriInterface, JsonSerializable { return $this->uri->__toString(); } + + /** + * Safely stringify input when possible for League UriInterface compatibility. + * + * @throws SyntaxError + */ + private function filterInput(mixed $str): string|null + { + if (!is_scalar($str) && !$str instanceof Stringable) { + throw new SyntaxError('The component must be a string, a scalar or a Stringable object; `'.gettype($str).'` given.'); + } + + $str = (string) $str; + if ('' === $str) { + return null; + } + + return $str; + } + + private function newInstance(UriInterface $uri): self + { + if ((string) $uri === (string) $this->uri) { + return $this; + } + + return new self($uri); + } + + /** + * {@inheritDoc} + */ + public function withScheme($scheme): self + { + return $this->newInstance($this->uri->withScheme($this->filterInput($scheme))); + } + + /** + * {@inheritDoc} + */ + public function withUserInfo($user, $password = null): self + { + return $this->newInstance($this->uri->withUserInfo($this->filterInput($user), $password)); + } + + /** + * {@inheritDoc} + */ + public function withHost($host): self + { + return $this->newInstance($this->uri->withHost($this->filterInput($host))); + } + + /** + * {@inheritDoc} + */ + public function withPort($port): self + { + return $this->newInstance($this->uri->withPort($port)); + } + + /** + * {@inheritDoc} + */ + public function withPath($path): self + { + return $this->newInstance($this->uri->withPath($path)); + } + + /** + * {@inheritDoc} + */ + public function withQuery($query): self + { + return $this->newInstance($this->uri->withQuery($this->filterInput($query))); + } + + /** + * {@inheritDoc} + */ + public function withFragment($fragment): self + { + return $this->newInstance($this->uri->withFragment($this->filterInput($fragment))); + } } diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/Uri.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/Uri.php index 77cb54bb..17e5611f 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/Uri.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/Uri.php @@ -21,8 +21,11 @@ use League\Uri\Exceptions\IdnSupportMissing; use League\Uri\Exceptions\SyntaxError; use League\Uri\Idna\Idna; use Psr\Http\Message\UriInterface as Psr7UriInterface; +use SensitiveParameter; +use Stringable; use TypeError; use function array_filter; +use function array_key_first; use function array_map; use function base64_decode; use function base64_encode; @@ -33,14 +36,15 @@ use function filter_var; use function implode; use function in_array; use function inet_pton; -use function is_object; +use function is_int; use function is_scalar; -use function method_exists; +use function is_string; +use function ltrim; use function preg_match; use function preg_replace; use function preg_replace_callback; use function rawurlencode; -use function sprintf; +use function str_contains; use function str_replace; use function strlen; use function strpos; @@ -81,14 +85,14 @@ final class Uri implements UriInterface * * @var string */ - private const REGEXP_CHARS_UNRESERVED = 'A-Za-z0-9_\-\.~'; + private const REGEXP_CHARS_UNRESERVED = 'A-Za-z\d_\-\.~'; /** * RFC3986 schema regular expression pattern. * * @link https://tools.ietf.org/html/rfc3986#section-3.1 */ - private const REGEXP_SCHEME = ',^[a-z]([-a-z0-9+.]+)?$,i'; + private const REGEXP_SCHEME = ',^[a-z]([-a-z\d+.]+)?$,i'; /** * RFC3986 host identified by a registered name regular expression pattern. @@ -96,9 +100,9 @@ final class Uri implements UriInterface * @link https://tools.ietf.org/html/rfc3986#section-3.2.2 */ private const REGEXP_HOST_REGNAME = '/^( - (?[a-z0-9_~\-\.])| + (?[a-z\d_~\-\.])| (?[!$&\'()*+,;=])| - (?%[A-F0-9]{2}) + (?%[A-F\d]{2}) )+$/x'; /** @@ -114,9 +118,9 @@ final class Uri implements UriInterface * @link https://tools.ietf.org/html/rfc3986#section-3.2.2 */ private const REGEXP_HOST_IPFUTURE = '/^ - v(?[A-F0-9])+\. + v(?[A-F\d])+\. (?: - (?[a-z0-9_~\-\.])| + (?[a-z\d_~\-\.])| (?[!$&\'()*+,;=:]) # also include the : character )+ $/ix'; @@ -176,20 +180,11 @@ final class Uri implements UriInterface ]; /** - * URI validation methods per scheme. + * Maximum number of formatted host cached. * - * @var array + * @var int */ - private const SCHEME_VALIDATION_METHOD = [ - 'data' => 'isUriWithSchemeAndPathOnly', - 'file' => 'isUriWithSchemeHostAndPathOnly', - 'ftp' => 'isNonEmptyHostUriWithoutFragmentAndQuery', - 'gopher' => 'isNonEmptyHostUriWithoutFragmentAndQuery', - 'http' => 'isNonEmptyHostUri', - 'https' => 'isNonEmptyHostUri', - 'ws' => 'isNonEmptyHostUriWithoutFragment', - 'wss' => 'isNonEmptyHostUriWithoutFragment', - ]; + private const MAXIMUM_FORMATTED_HOST_CACHED = 100; /** * All ASCII letters sorted by typical frequency of occurrence. @@ -203,7 +198,7 @@ final class Uri implements UriInterface private ?string $host; private ?int $port; private ?string $authority; - private string $path = ''; + private string $path; private ?string $query; private ?string $fragment; private ?string $uri; @@ -211,7 +206,7 @@ final class Uri implements UriInterface private function __construct( ?string $scheme, ?string $user, - ?string $pass, + #[SensitiveParameter] ?string $pass, ?string $host, ?int $port, string $path, @@ -226,49 +221,49 @@ final class Uri implements UriInterface $this->path = $this->formatPath($path); $this->query = $this->formatQueryAndFragment($query); $this->fragment = $this->formatQueryAndFragment($fragment); + $this->assertValidState(); } /** * Format the Scheme and Host component. * - * @param ?string $scheme * @throws SyntaxError if the scheme is invalid */ private function formatScheme(?string $scheme): ?string { - if (null === $scheme) { + if (null === $scheme || array_key_exists($scheme, self::SCHEME_DEFAULT_PORT)) { return $scheme; } $formatted_scheme = strtolower($scheme); - if (1 === preg_match(self::REGEXP_SCHEME, $formatted_scheme)) { + if (array_key_exists($formatted_scheme, self::SCHEME_DEFAULT_PORT) || 1 === preg_match(self::REGEXP_SCHEME, $formatted_scheme)) { return $formatted_scheme; } - throw new SyntaxError(sprintf('The scheme `%s` is invalid.', $scheme)); + throw new SyntaxError('The scheme `'.$scheme.'` is invalid.'); } /** * Set the UserInfo component. - * @param ?string $user - * @param ?string $password */ - private function formatUserInfo(?string $user, ?string $password): ?string - { + private function formatUserInfo( + ?string $user, + #[SensitiveParameter] ?string $password + ): ?string { if (null === $user) { - return $user; + return null; } - static $user_pattern = '/(?:[^%'.self::REGEXP_CHARS_UNRESERVED.self::REGEXP_CHARS_SUBDELIM.']++|%(?![A-Fa-f0-9]{2}))/'; - $user = preg_replace_callback($user_pattern, [Uri::class, 'urlEncodeMatch'], $user); + static $user_pattern = '/[^%'.self::REGEXP_CHARS_UNRESERVED.self::REGEXP_CHARS_SUBDELIM.']++|%(?![A-Fa-f\d]{2})/'; + $user = preg_replace_callback($user_pattern, Uri::urlEncodeMatch(...), $user); if (null === $password) { return $user; } - static $password_pattern = '/(?:[^%:'.self::REGEXP_CHARS_UNRESERVED.self::REGEXP_CHARS_SUBDELIM.']++|%(?![A-Fa-f0-9]{2}))/'; + static $password_pattern = '/[^%:'.self::REGEXP_CHARS_UNRESERVED.self::REGEXP_CHARS_SUBDELIM.']++|%(?![A-Fa-f\d]{2})/'; - return $user.':'.preg_replace_callback($password_pattern, [Uri::class, 'urlEncodeMatch'], $password); + return $user.':'.preg_replace_callback($password_pattern, Uri::urlEncodeMatch(...), $password); } /** @@ -281,7 +276,6 @@ final class Uri implements UriInterface /** * Validate and Format the Host component. - * @param ?string $host */ private function formatHost(?string $host): ?string { @@ -289,11 +283,18 @@ final class Uri implements UriInterface return $host; } - if ('[' !== $host[0]) { - return $this->formatRegisteredName($host); + static $formattedHostCache = []; + if (isset($formattedHostCache[$host])) { + return $formattedHostCache[$host]; } - return $this->formatIp($host); + $formattedHost = '[' === $host[0] ? $this->formatIp($host) : $this->formatRegisteredName($host); + $formattedHostCache[$host] = $formattedHost; + if (self::MAXIMUM_FORMATTED_HOST_CACHED < count($formattedHostCache)) { + unset($formattedHostCache[array_key_first($formattedHostCache)]); + } + + return $formattedHost; } /** @@ -312,7 +313,7 @@ final class Uri implements UriInterface } if (1 === preg_match(self::REGEXP_HOST_GEN_DELIMS, $formatted_host)) { - throw new SyntaxError(sprintf('The host `%s` is invalid : a registered name can not contain URI delimiters or spaces', $host)); + throw new SyntaxError('The host `'.$host.'` is invalid : a registered name can not contain URI delimiters or spaces.'); } $info = Idna::toAscii($host, Idna::IDNA2008_ASCII); @@ -341,35 +342,33 @@ final class Uri implements UriInterface $pos = strpos($ip, '%'); if (false === $pos) { - throw new SyntaxError(sprintf('The host `%s` is invalid : the IP host is malformed', $host)); + throw new SyntaxError('The host `'.$host.'` is invalid : the IP host is malformed.'); } if (1 === preg_match(self::REGEXP_HOST_GEN_DELIMS, rawurldecode(substr($ip, $pos)))) { - throw new SyntaxError(sprintf('The host `%s` is invalid : the IP host is malformed', $host)); + throw new SyntaxError('The host `'.$host.'` is invalid : the IP host is malformed.'); } $ip = substr($ip, 0, $pos); if (false === filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { - throw new SyntaxError(sprintf('The host `%s` is invalid : the IP host is malformed', $host)); + throw new SyntaxError('The host `'.$host.'` is invalid : the IP host is malformed.'); } //Only the address block fe80::/10 can have a Zone ID attach to //let's detect the link local significant 10 bits - if (0 === strpos((string) inet_pton($ip), self::HOST_ADDRESS_BLOCK)) { + if (str_starts_with((string)inet_pton($ip), self::HOST_ADDRESS_BLOCK)) { return $host; } - throw new SyntaxError(sprintf('The host `%s` is invalid : the IP host is malformed', $host)); + throw new SyntaxError('The host `'.$host.'` is invalid : the IP host is malformed.'); } /** * Format the Port component. * - * @param object|null|int|string $port - * * @throws SyntaxError */ - private function formatPort($port = null): ?int + private function formatPort(Stringable|string|int|null $port = null): ?int { if (null === $port || '' === $port) { return null; @@ -381,7 +380,7 @@ final class Uri implements UriInterface $port = (int) $port; if (0 > $port) { - throw new SyntaxError(sprintf('The port `%s` is invalid', $port)); + throw new SyntaxError('The port `'.$port.'` is invalid.'); } $defaultPort = self::SCHEME_DEFAULT_PORT[$this->scheme] ?? null; @@ -392,9 +391,6 @@ final class Uri implements UriInterface return $port; } - /** - * {@inheritDoc} - */ public static function __set_state(array $components): self { $components['user'] = null; @@ -416,22 +412,21 @@ final class Uri implements UriInterface } /** - * Create a new instance from a URI and a Base URI. + * Creates a new instance from a URI and a Base URI. * * The returned URI must be absolute. - * - * @param mixed $uri the input URI to create - * @param null|mixed $base_uri the base URI used for reference */ - public static function createFromBaseUri($uri, $base_uri = null): UriInterface - { + public static function createFromBaseUri( + Stringable|UriInterface|String $uri, + Stringable|UriInterface|String $base_uri = null + ): UriInterface { if (!$uri instanceof UriInterface) { $uri = self::createFromString($uri); } if (null === $base_uri) { if (null === $uri->getScheme()) { - throw new SyntaxError(sprintf('the URI `%s` must be absolute', (string) $uri)); + throw new SyntaxError('the URI `'.$uri.'` must be absolute.'); } if (null === $uri->getAuthority()) { @@ -449,7 +444,7 @@ final class Uri implements UriInterface } if (null === $base_uri->getScheme()) { - throw new SyntaxError(sprintf('the base URI `%s` must be absolute', (string) $base_uri)); + throw new SyntaxError('the base URI `'.$base_uri.'` must be absolute.'); } /** @var UriInterface $uri */ @@ -460,10 +455,8 @@ final class Uri implements UriInterface /** * Create a new instance from a string. - * - * @param string|mixed $uri */ - public static function createFromString($uri = ''): self + public static function createFromString(Stringable|string $uri = ''): self { $components = UriString::parse($uri); @@ -517,7 +510,7 @@ final class Uri implements UriInterface // @codeCoverageIgnoreStart if (!$finfo_support) { - throw new FileinfoSupportMissing(sprintf('Please install ext/fileinfo to use the %s() method.', __METHOD__)); + throw new FileinfoSupportMissing('Please install ext/fileinfo to use the '.__METHOD__.'() method.'); } // @codeCoverageIgnoreEnd @@ -528,9 +521,12 @@ final class Uri implements UriInterface $mime_args[] = $context; } - $raw = @file_get_contents(...$file_args); + set_error_handler(fn (int $errno, string $errstr, string $errfile, int $errline) => true); + $raw = file_get_contents(...$file_args); + restore_error_handler(); + if (false === $raw) { - throw new SyntaxError(sprintf('The file `%s` does not exist or is not readable', $path)); + throw new SyntaxError('The file `'.$path.'` does not exist or is not readable.'); } $mimetype = (string) (new finfo(FILEINFO_MIME))->file(...$mime_args); @@ -546,7 +542,7 @@ final class Uri implements UriInterface */ public static function createFromUnixPath(string $uri = ''): self { - $uri = implode('/', array_map('rawurlencode', explode('/', $uri))); + $uri = implode('/', array_map(rawurlencode(...), explode('/', $uri))); if ('/' !== ($uri[0] ?? '')) { return Uri::createFromComponents(['path' => $uri]); } @@ -565,7 +561,7 @@ final class Uri implements UriInterface $uri = substr($uri, strlen($root)); } $uri = str_replace('\\', '/', $uri); - $uri = implode('/', array_map('rawurlencode', explode('/', $uri))); + $uri = implode('/', array_map(rawurlencode(...), explode('/', $uri))); //Local Windows absolute path if ('' !== $root) { @@ -573,7 +569,7 @@ final class Uri implements UriInterface } //UNC Windows Path - if ('//' !== substr($uri, 0, 2)) { + if (!str_starts_with($uri, '//')) { return Uri::createFromComponents(['path' => $uri]); } @@ -584,10 +580,8 @@ final class Uri implements UriInterface /** * Create a new instance from a URI object. - * - * @param Psr7UriInterface|UriInterface $uri the input URI to create */ - public static function createFromUri($uri): self + public static function createFromUri(Psr7UriInterface|UriInterface $uri): self { if ($uri instanceof UriInterface) { $user_info = $uri->getUserInfo(); @@ -609,10 +603,6 @@ final class Uri implements UriInterface ); } - if (!$uri instanceof Psr7UriInterface) { - throw new TypeError(sprintf('The object must implement the `%s` or the `%s`', Psr7UriInterface::class, UriInterface::class)); - } - $scheme = $uri->getScheme(); if ('' === $scheme) { $scheme = null; @@ -657,19 +647,12 @@ final class Uri implements UriInterface */ public static function createFromServer(array $server): self { - [$user, $pass] = self::fetchUserInfo($server); - [$host, $port] = self::fetchHostname($server); - [$path, $query] = self::fetchRequestUri($server); + $components = ['scheme' => self::fetchScheme($server)]; + [$components['user'], $components['pass']] = self::fetchUserInfo($server); + [$components['host'], $components['port']] = self::fetchHostname($server); + [$components['path'], $components['query']] = self::fetchRequestUri($server); - return Uri::createFromComponents([ - 'scheme' => self::fetchScheme($server), - 'user' => $user, - 'pass' => $pass, - 'host' => $host, - 'port' => $port, - 'path' => $path, - 'query' => $query, - ]); + return Uri::createFromComponents($components); } /** @@ -686,14 +669,14 @@ final class Uri implements UriInterface /** * Returns the environment user info. * - * @return array{0:?string, 1:?string} + * @return non-empty-array{0:?string, 1:?string} */ private static function fetchUserInfo(array $server): array { $server += ['PHP_AUTH_USER' => null, 'PHP_AUTH_PW' => null, 'HTTP_AUTHORIZATION' => '']; $user = $server['PHP_AUTH_USER']; $pass = $server['PHP_AUTH_PW']; - if (0 === strpos(strtolower($server['HTTP_AUTHORIZATION']), 'basic')) { + if (str_starts_with(strtolower($server['HTTP_AUTHORIZATION']), 'basic')) { $userinfo = base64_decode(substr($server['HTTP_AUTHORIZATION'], 6), true); if (false === $userinfo) { throw new SyntaxError('The user info could not be detected'); @@ -751,20 +734,17 @@ final class Uri implements UriInterface /** * Returns the environment path. * - * @return array{0:?string, 1:?string} + * @return non-empty-array{0:?string, 1:?string} */ private static function fetchRequestUri(array $server): array { $server += ['IIS_WasUrlRewritten' => null, 'UNENCODED_URL' => '', 'PHP_SELF' => '', 'QUERY_STRING' => null]; if ('1' === $server['IIS_WasUrlRewritten'] && '' !== $server['UNENCODED_URL']) { - /** @var array{0:?string, 1:?string} $retval */ - $retval = explode('?', $server['UNENCODED_URL'], 2) + [1 => null]; - - return $retval; + return explode('?', $server['UNENCODED_URL'], 2) + [1 => null]; } if (isset($server['REQUEST_URI'])) { - [$path, ] = explode('?', $server['REQUEST_URI'], 2); + [$path] = explode('?', $server['REQUEST_URI'], 2); $query = ('' !== $server['QUERY_STRING']) ? $server['QUERY_STRING'] : null; return [$path, $query]; @@ -799,13 +779,21 @@ final class Uri implements UriInterface */ private function formatPath(string $path): string { - $path = $this->formatDataPath($path); + if ('data' === $this->scheme) { + $path = $this->formatDataPath($path); + } - static $pattern = '/(?:[^'.self::REGEXP_CHARS_UNRESERVED.self::REGEXP_CHARS_SUBDELIM.'%:@\/}{]++|%(?![A-Fa-f0-9]{2}))/'; + if ('/' !== $path) { + static $pattern = '/[^'.self::REGEXP_CHARS_UNRESERVED.self::REGEXP_CHARS_SUBDELIM.':@\/}{]++|%(?![A-Fa-f\d]{2})/'; - $path = (string) preg_replace_callback($pattern, [Uri::class, 'urlEncodeMatch'], $path); + $path = (string) preg_replace_callback($pattern, Uri::urlEncodeMatch(...), $path); + } - return $this->formatFilePath($path); + if ('file' === $this->scheme) { + $path = $this->formatFilePath($path); + } + + return $path; } /** @@ -817,16 +805,12 @@ final class Uri implements UriInterface */ private function formatDataPath(string $path): string { - if ('data' !== $this->scheme) { - return $path; - } - if ('' == $path) { return 'text/plain;charset=us-ascii,'; } - if (strlen($path) !== strspn($path, self::ASCII) || false === strpos($path, ',')) { - throw new SyntaxError(sprintf('The path `%s` is invalid according to RFC2937', $path)); + if (strlen($path) !== strspn($path, self::ASCII) || !str_contains($path, ',')) { + throw new SyntaxError('The path `'.$path.'` is invalid according to RFC2937.'); } $parts = explode(',', $path, 2) + [1 => null]; @@ -857,7 +841,7 @@ final class Uri implements UriInterface private function assertValidPath(string $mimetype, string $parameters, string $data): void { if (1 !== preg_match(self::REGEXP_MIMETYPE, $mimetype)) { - throw new SyntaxError(sprintf('The path mimetype `%s` is invalid', $mimetype)); + throw new SyntaxError('The path mimetype `'.$mimetype.'` is invalid.'); } $is_binary = 1 === preg_match(self::REGEXP_BINARY, $parameters, $matches); @@ -865,9 +849,9 @@ final class Uri implements UriInterface $parameters = substr($parameters, 0, - strlen($matches[0])); } - $res = array_filter(array_filter(explode(';', $parameters), [$this, 'validateParameter'])); + $res = array_filter(array_filter(explode(';', $parameters), $this->validateParameter(...))); if ([] !== $res) { - throw new SyntaxError(sprintf('The path paremeters `%s` is invalid', $parameters)); + throw new SyntaxError('The path paremeters `'.$parameters.'` is invalid.'); } if (!$is_binary) { @@ -876,7 +860,7 @@ final class Uri implements UriInterface $res = base64_decode($data, true); if (false === $res || $data !== base64_encode($res)) { - throw new SyntaxError(sprintf('The path data `%s` is invalid', $data)); + throw new SyntaxError('The path data `'.$data.'` is invalid.'); } } @@ -895,10 +879,6 @@ final class Uri implements UriInterface */ private function formatFilePath(string $path): string { - if ('file' !== $this->scheme) { - return $path; - } - $replace = static function (array $matches): string { return $matches['delim'].$matches['volume'].':'.$matches['rest']; }; @@ -915,8 +895,6 @@ final class Uri implements UriInterface *
  • a boolean flag telling wether the delimiter is to be added to the component * when building the URI string representation
  • * - * - * @param ?string $component */ private function formatQueryAndFragment(?string $component): ?string { @@ -924,8 +902,8 @@ final class Uri implements UriInterface return $component; } - static $pattern = '/(?:[^'.self::REGEXP_CHARS_UNRESERVED.self::REGEXP_CHARS_SUBDELIM.'%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/'; - return preg_replace_callback($pattern, [Uri::class, 'urlEncodeMatch'], $component); + static $pattern = '/[^'.self::REGEXP_CHARS_UNRESERVED.self::REGEXP_CHARS_SUBDELIM.':@\/?]++|%(?![A-Fa-f\d]{2})/'; + return preg_replace_callback($pattern, Uri::urlEncodeMatch(...), $component); } /** @@ -943,27 +921,31 @@ final class Uri implements UriInterface throw new SyntaxError('If an authority is present the path must be empty or start with a `/`.'); } - if (null === $this->authority && 0 === strpos($this->path, '//')) { - throw new SyntaxError(sprintf('If there is no authority the path `%s` can not start with a `//`.', $this->path)); + if (null === $this->authority && str_starts_with($this->path, '//')) { + throw new SyntaxError('If there is no authority the path `'.$this->path.'` can not start with a `//`.'); } $pos = strpos($this->path, ':'); if (null === $this->authority && null === $this->scheme && false !== $pos - && false === strpos(substr($this->path, 0, $pos), '/') + && !str_contains(substr($this->path, 0, $pos), '/') ) { throw new SyntaxError('In absence of a scheme and an authority the first path segment cannot contain a colon (":") character.'); } - $validationMethod = self::SCHEME_VALIDATION_METHOD[$this->scheme] ?? null; - if (null === $validationMethod || true === $this->$validationMethod()) { - $this->uri = null; + $this->uri = null; - return; + if (! match ($this->scheme) { + 'data' => $this->isUriWithSchemeAndPathOnly(), + 'file' => $this->isUriWithSchemeHostAndPathOnly(), + 'ftp', 'gopher' => $this->isNonEmptyHostUriWithoutFragmentAndQuery(), + 'http', 'https' => $this->isNonEmptyHostUri(), + 'ws', 'wss' => $this->isNonEmptyHostUriWithoutFragment(), + default => true, + }) { + throw new SyntaxError('The uri `'.$this.'` is invalid for the `'.$this->scheme.'` scheme.'); } - - throw new SyntaxError(sprintf('The uri `%s` is invalid for the `%s` scheme.', (string) $this, $this->scheme)); } /** @@ -1019,11 +1001,6 @@ final class Uri implements UriInterface * Generate the URI string representation from its components. * * @link https://tools.ietf.org/html/rfc3986#section-5.3 - * - * @param ?string $scheme - * @param ?string $authority - * @param ?string $query - * @param ?string $fragment */ private function getUriString( ?string $scheme, @@ -1053,15 +1030,13 @@ final class Uri implements UriInterface public function toString(): string { - $this->uri = $this->uri ?? $this->getUriString( + return $this->uri ??= $this->getUriString( $this->scheme, $this->authority, $this->path, $this->query, $this->fragment ); - - return $this->uri; } /** @@ -1081,9 +1056,15 @@ final class Uri implements UriInterface } /** - * {@inheritDoc} - * - * @return array{scheme:?string, user_info:?string, host:?string, port:?int, path:string, query:?string, fragment:?string} + * @return array{ + * scheme:?string, + * user_info:?string, + * host:?string, + * port:?int, + * path:string, + * query:?string, + * fragment:?string + * } */ public function __debugInfo(): array { @@ -1143,7 +1124,7 @@ final class Uri implements UriInterface */ public function getPath(): string { - if (0 === strpos($this->path, '//')) { + if (str_starts_with($this->path, '//')) { return '/'.ltrim($this->path, '/'); } @@ -1192,18 +1173,14 @@ final class Uri implements UriInterface * * @throws SyntaxError if the submitted data can not be converted to string */ - private function filterString($str): ?string + private function filterString(mixed $str): ?string { if (null === $str) { - return $str; + return null; } - if (is_object($str) && method_exists($str, '__toString')) { - $str = (string) $str; - } - - if (!is_scalar($str)) { - throw new SyntaxError(sprintf('The component must be a string, a scalar or a stringable object; `%s` given.', gettype($str))); + if (!is_scalar($str) && !$str instanceof Stringable) { + throw new SyntaxError('The component must be a string, a scalar or a Stringable object; `'.gettype($str).'` given.'); } $str = (string) $str; @@ -1211,14 +1188,16 @@ final class Uri implements UriInterface return $str; } - throw new SyntaxError(sprintf('The component `%s` contains invalid characters.', $str)); + throw new SyntaxError('The component `'.$str.'` contains invalid characters.'); } /** * {@inheritDoc} */ - public function withUserInfo($user, $password = null): UriInterface - { + public function withUserInfo( + $user, + #[SensitiveParameter] $password = null + ): UriInterface { $user_info = null; $user = $this->filterString($user); if (null !== $password) { diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriInfo.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriInfo.php index ec8473c5..83fa77e5 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriInfo.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriInfo.php @@ -15,18 +15,15 @@ namespace League\Uri; use League\Uri\Contracts\UriInterface; use Psr\Http\Message\UriInterface as Psr7UriInterface; -use TypeError; use function explode; use function implode; use function preg_replace_callback; use function rawurldecode; -use function sprintf; final class UriInfo { - private const REGEXP_ENCODED_CHARS = ',%(2[D|E]|3[0-9]|4[1-9|A-F]|5[0-9|AF]|6[1-9|A-F]|7[0-9|E]),i'; - - private const WHATWG_SPECIAL_SCHEMES = ['ftp' => 21, 'http' => 80, 'https' => 443, 'ws' => 80, 'wss' => 443]; + private const REGEXP_ENCODED_CHARS = ',%(2[D|E]|3\d|4[1-9|A-F]|5[\d|A|F]|6[1-9|A-F]|7[\d|E]),i'; + private const WHATWG_SPECIAL_SCHEMES = ['ftp', 'http', 'https', 'ws', 'wss']; /** * @codeCoverageIgnore @@ -35,46 +32,17 @@ final class UriInfo { } - /** - * @param Psr7UriInterface|UriInterface $uri - */ - private static function emptyComponentValue($uri): ?string + + private static function emptyComponentValue(Psr7UriInterface|UriInterface $uri): ?string { return $uri instanceof Psr7UriInterface ? '' : null; } /** - * Filter the URI object. - * - * To be valid an URI MUST implement at least one of the following interface: - * - League\Uri\UriInterface - * - Psr\Http\Message\UriInterface - * - * @param mixed $uri the URI to validate - * - * @throws TypeError if the URI object does not implements the supported interfaces. - * - * @return Psr7UriInterface|UriInterface + * Normalizes an URI for comparison. */ - private static function filterUri($uri) + private static function normalize(Psr7UriInterface|UriInterface $uri): Psr7UriInterface|UriInterface { - if ($uri instanceof Psr7UriInterface || $uri instanceof UriInterface) { - return $uri; - } - - throw new TypeError(sprintf('The uri must be a valid URI object received `%s`', is_object($uri) ? get_class($uri) : gettype($uri))); - } - - /** - * Normalize an URI for comparison. - * - * @param Psr7UriInterface|UriInterface $uri - * - * @return Psr7UriInterface|UriInterface - */ - private static function normalize($uri) - { - $uri = self::filterUri($uri); $null = self::emptyComponentValue($uri); $path = $uri->getPath(); @@ -107,36 +75,28 @@ final class UriInfo } /** - * Tell whether the URI represents an absolute URI. - * - * @param Psr7UriInterface|UriInterface $uri + * Tells whether the URI represents an absolute URI. */ - public static function isAbsolute($uri): bool + public static function isAbsolute(Psr7UriInterface|UriInterface $uri): bool { - return self::emptyComponentValue($uri) !== self::filterUri($uri)->getScheme(); + return self::emptyComponentValue($uri) !== $uri->getScheme(); } /** * Tell whether the URI represents a network path. - * - * @param Psr7UriInterface|UriInterface $uri */ - public static function isNetworkPath($uri): bool + public static function isNetworkPath(Psr7UriInterface|UriInterface $uri): bool { - $uri = self::filterUri($uri); $null = self::emptyComponentValue($uri); return $null === $uri->getScheme() && $null !== $uri->getAuthority(); } /** - * Tell whether the URI represents an absolute path. - * - * @param Psr7UriInterface|UriInterface $uri + * Tells whether the URI represents an absolute path. */ - public static function isAbsolutePath($uri): bool + public static function isAbsolutePath(Psr7UriInterface|UriInterface $uri): bool { - $uri = self::filterUri($uri); $null = self::emptyComponentValue($uri); return $null === $uri->getScheme() @@ -147,11 +107,9 @@ final class UriInfo /** * Tell whether the URI represents a relative path. * - * @param Psr7UriInterface|UriInterface $uri */ - public static function isRelativePath($uri): bool + public static function isRelativePath(Psr7UriInterface|UriInterface $uri): bool { - $uri = self::filterUri($uri); $null = self::emptyComponentValue($uri); return $null === $uri->getScheme() @@ -160,12 +118,9 @@ final class UriInfo } /** - * Tell whether both URI refers to the same document. - * - * @param Psr7UriInterface|UriInterface $uri - * @param Psr7UriInterface|UriInterface $base_uri + * Tells whether both URI refers to the same document. */ - public static function isSameDocument($uri, $base_uri): bool + public static function isSameDocument(Psr7UriInterface|UriInterface $uri, Psr7UriInterface|UriInterface $base_uri): bool { $uri = self::normalize($uri); $base_uri = self::normalize($base_uri); @@ -182,31 +137,30 @@ final class UriInfo * For URI without a special scheme the method returns null * For URI with the file scheme the method will return null (as this is left to the implementation decision) * For URI with a special scheme the method returns the scheme followed by its authority (without the userinfo part) - * - * @param Psr7UriInterface|UriInterface $uri */ - public static function getOrigin($uri): ?string + public static function getOrigin(Psr7UriInterface|UriInterface $uri): ?string { - $scheme = self::filterUri($uri)->getScheme(); + $scheme = $uri->getScheme(); if ('blob' === $scheme) { $uri = Uri::createFromString($uri->getPath()); $scheme = $uri->getScheme(); } - if (null === $scheme || !array_key_exists($scheme, self::WHATWG_SPECIAL_SCHEMES)) { - return null; + if (in_array($scheme, self::WHATWG_SPECIAL_SCHEMES, true)) { + $null = self::emptyComponentValue($uri); + + return (string) $uri->withFragment($null)->withQuery($null)->withPath('')->withUserInfo($null, null); } - $null = self::emptyComponentValue($uri); - - return (string) $uri->withFragment($null)->withQuery($null)->withPath('')->withUserInfo($null); + return null; } /** - * @param Psr7UriInterface|UriInterface $uri - * @param Psr7UriInterface|UriInterface $base_uri + * Tells whether two URI do not share the same origin. + * + * @see UriInfo::getOrigin() */ - public static function isCrossOrigin($uri, $base_uri): bool + public static function isCrossOrigin(Psr7UriInterface|UriInterface $uri, Psr7UriInterface|UriInterface $base_uri): bool { return null === ($uriString = self::getOrigin(Uri::createFromUri($uri))) || null === ($baseUriString = self::getOrigin(Uri::createFromUri($base_uri))) diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriResolver.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriResolver.php index 1090383c..844a3d30 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriResolver.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriResolver.php @@ -15,16 +15,13 @@ namespace League\Uri; use League\Uri\Contracts\UriInterface; use Psr\Http\Message\UriInterface as Psr7UriInterface; -use TypeError; use function array_pop; use function array_reduce; use function count; use function end; use function explode; -use function gettype; use function implode; use function in_array; -use function sprintf; use function str_repeat; use function strpos; use function substr; @@ -44,20 +41,13 @@ final class UriResolver } /** - * Resolve an URI against a base URI using RFC3986 rules. + * Resolves an URI against a base URI using RFC3986 rules. * * If the first argument is a UriInterface the method returns a UriInterface object * If the first argument is a Psr7UriInterface the method returns a Psr7UriInterface object - * - * @param Psr7UriInterface|UriInterface $uri - * @param Psr7UriInterface|UriInterface $base_uri - * - * @return Psr7UriInterface|UriInterface */ - public static function resolve($uri, $base_uri) + public static function resolve(Psr7UriInterface|UriInterface $uri, Psr7UriInterface|UriInterface $base_uri): Psr7UriInterface|UriInterface { - self::filterUri($uri); - self::filterUri($base_uri); $null = $uri instanceof Psr7UriInterface ? '' : null; if ($null !== $uri->getScheme()) { @@ -90,38 +80,24 @@ final class UriResolver ; } - /** - * Filter the URI object. - * - * @param mixed $uri an URI object - * - * @throws TypeError if the URI object does not implements the supported interfaces. - */ - private static function filterUri($uri): void - { - if (!$uri instanceof UriInterface && !$uri instanceof Psr7UriInterface) { - throw new TypeError(sprintf('The uri must be a valid URI object received `%s`', gettype($uri))); - } - } - /** * Remove dot segments from the URI path. */ private static function removeDotSegments(string $path): string { - if (false === strpos($path, '.')) { + if (!str_contains($path, '.')) { return $path; } $old_segments = explode('/', $path); - $new_path = implode('/', array_reduce($old_segments, [UriResolver::class, 'reducer'], [])); + $new_path = implode('/', array_reduce($old_segments, UriResolver::reducer(...), [])); if (isset(self::DOT_SEGMENTS[end($old_segments)])) { $new_path .= '/'; } // @codeCoverageIgnoreStart // added because some PSR-7 implementations do not respect RFC3986 - if (0 === strpos($path, '/') && 0 !== strpos($new_path, '/')) { + if (str_starts_with($path, '/') && !str_starts_with($new_path, '/')) { return '/'.$new_path; } // @codeCoverageIgnoreEnd @@ -150,21 +126,20 @@ final class UriResolver } /** - * Resolve an URI path and query component. - * - * @param Psr7UriInterface|UriInterface $uri - * @param Psr7UriInterface|UriInterface $base_uri + * Resolves an URI path and query component. * * @return array{0:string, 1:string|null} */ - private static function resolvePathAndQuery($uri, $base_uri): array - { + private static function resolvePathAndQuery( + Psr7UriInterface|UriInterface $uri, + Psr7UriInterface|UriInterface $base_uri + ): array { $target_path = $uri->getPath(); $target_query = $uri->getQuery(); $null = $uri instanceof Psr7UriInterface ? '' : null; $baseNull = $base_uri instanceof Psr7UriInterface ? '' : null; - if (0 === strpos($target_path, '/')) { + if (str_starts_with($target_path, '/')) { return [$target_path, $target_query]; } @@ -176,7 +151,7 @@ final class UriResolver $target_path = $base_uri->getPath(); //@codeCoverageIgnoreStart //because some PSR-7 Uri implementations allow this RFC3986 forbidden construction - if ($baseNull !== $base_uri->getAuthority() && 0 !== strpos($target_path, '/')) { + if ($baseNull !== $base_uri->getAuthority() && !str_starts_with($target_path, '/')) { $target_path = '/'.$target_path; } //@codeCoverageIgnoreEnd @@ -201,23 +176,18 @@ final class UriResolver } /** - * Relativize an URI according to a base URI. + * Relativizes an URI according to a base URI. * * This method MUST retain the state of the submitted URI instance, and return * an URI instance of the same type that contains the applied modifications. * * This method MUST be transparent when dealing with error and exceptions. * It MUST not alter of silence them apart from validating its own parameters. - * - * @param Psr7UriInterface|UriInterface $uri - * @param Psr7UriInterface|UriInterface $base_uri - * - * @return Psr7UriInterface|UriInterface */ - public static function relativize($uri, $base_uri) - { - self::filterUri($uri); - self::filterUri($base_uri); + public static function relativize( + Psr7UriInterface|UriInterface $uri, + Psr7UriInterface|UriInterface $base_uri + ): Psr7UriInterface|UriInterface { $uri = self::formatHost($uri); $base_uri = self::formatHost($base_uri); if (!self::isRelativizable($uri, $base_uri)) { @@ -231,7 +201,7 @@ final class UriResolver return $uri->withPath(self::relativizePath($target_path, $base_uri->getPath())); } - if (self::componentEquals('getQuery', $uri, $base_uri)) { + if (self::componentEquals('query', $uri, $base_uri)) { return $uri->withPath('')->withQuery($null); } @@ -244,23 +214,26 @@ final class UriResolver /** * Tells whether the component value from both URI object equals. - * - * @param Psr7UriInterface|UriInterface $uri - * @param Psr7UriInterface|UriInterface $base_uri */ - private static function componentEquals(string $method, $uri, $base_uri): bool - { - return self::getComponent($method, $uri) === self::getComponent($method, $base_uri); + private static function componentEquals( + string $property, + Psr7UriInterface|UriInterface $uri, + Psr7UriInterface|UriInterface $base_uri + ): bool { + return self::getComponent($property, $uri) === self::getComponent($property, $base_uri); } /** * Returns the component value from the submitted URI object. - * - * @param Psr7UriInterface|UriInterface $uri */ - private static function getComponent(string $method, $uri): ?string + private static function getComponent(string $property, Psr7UriInterface|UriInterface $uri): ?string { - $component = $uri->$method(); + $component = match ($property) { + 'query' => $uri->getQuery(), + 'authority' => $uri->getAuthority(), + default => $uri->getScheme(), //scheme + }; + if ($uri instanceof Psr7UriInterface && '' === $component) { return null; } @@ -270,14 +243,8 @@ final class UriResolver /** * Filter the URI object. - * - * @param Psr7UriInterface|UriInterface $uri - * - * @throws TypeError if the URI object does not implements the supported interfaces. - * - * @return Psr7UriInterface|UriInterface */ - private static function formatHost($uri) + private static function formatHost(Psr7UriInterface|UriInterface $uri): Psr7UriInterface|UriInterface { if (!$uri instanceof Psr7UriInterface) { return $uri; @@ -292,20 +259,19 @@ final class UriResolver } /** - * Tell whether the submitted URI object can be relativize. - * - * @param Psr7UriInterface|UriInterface $uri - * @param Psr7UriInterface|UriInterface $base_uri + * Tells whether the submitted URI object can be relativize. */ - private static function isRelativizable($uri, $base_uri): bool - { + private static function isRelativizable( + Psr7UriInterface|UriInterface $uri, + Psr7UriInterface|UriInterface $base_uri + ): bool { return !UriInfo::isRelativePath($uri) - && self::componentEquals('getScheme', $uri, $base_uri) - && self::componentEquals('getAuthority', $uri, $base_uri); + && self::componentEquals('scheme', $uri, $base_uri) + && self::componentEquals('authority', $uri, $base_uri); } /** - * Relative the URI for a authority-less target URI. + * Relatives the URI for an authority-less target URI. */ private static function relativizePath(string $path, string $basepath): string { diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriString.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriString.php index 674e1a43..93dd928d 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriString.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriString.php @@ -17,15 +17,11 @@ use League\Uri\Exceptions\IdnaConversionFailed; use League\Uri\Exceptions\IdnSupportMissing; use League\Uri\Exceptions\SyntaxError; use League\Uri\Idna\Idna; -use TypeError; +use Stringable; use function array_merge; use function explode; use function filter_var; -use function gettype; use function inet_pton; -use function is_object; -use function is_scalar; -use function method_exists; use function preg_match; use function rawurldecode; use function sprintf; @@ -87,7 +83,7 @@ final class UriString * * @link https://tools.ietf.org/html/rfc3986#section-3.1 */ - private const REGEXP_URI_SCHEME = '/^([a-z][a-z\d\+\.\-]*)?$/i'; + private const REGEXP_URI_SCHEME = '/^([a-z][a-z\d+.-]*)?$/i'; /** * IPvFuture regular expression. @@ -157,16 +153,7 @@ final class UriString * @link https://tools.ietf.org/html/rfc3986#section-5.3 * @link https://tools.ietf.org/html/rfc3986#section-7.5 * - * @param array{ - * scheme:?string, - * user:?string, - * pass:?string, - * host:?string, - * port:?int, - * path:?string, - * query:?string, - * fragment:?string - * } $components + * @param array{scheme:?string, user:?string, pass:?string, host:?string, port:?int, path:?string, query:?string, fragment:?string} $components */ public static function build(array $components): string { @@ -242,35 +229,17 @@ final class UriString * * @link https://tools.ietf.org/html/rfc3986 * - * @param mixed $uri any scalar or stringable object + * @param Stringable|string|int|float $uri any scalar or stringable object * * @throws SyntaxError if the URI contains invalid characters * @throws SyntaxError if the URI contains an invalid scheme * @throws SyntaxError if the URI contains an invalid path * - * @return array{ - * scheme:?string, - * user:?string, - * pass:?string, - * host:?string, - * port:?int, - * path:string, - * query:?string, - * fragment:?string - * } + * @return array{scheme:?string, user:?string, pass:?string, host:?string, port:?int, path:string, query:?string, fragment:?string} */ - public static function parse($uri): array + public static function parse(Stringable|string|int|float $uri): array { - if (is_object($uri) && method_exists($uri, '__toString')) { - $uri = (string) $uri; - } - - if (!is_scalar($uri)) { - throw new TypeError(sprintf('The uri must be a scalar or a stringable object `%s` given', gettype($uri))); - } - $uri = (string) $uri; - if (isset(self::URI_SCHORTCUTS[$uri])) { /** @var array{scheme:?string, user:?string, pass:?string, host:?string, port:?int, path:string, query:?string, fragment:?string} $components */ $components = array_merge(self::URI_COMPONENTS, self::URI_SCHORTCUTS[$uri]); @@ -395,7 +364,7 @@ final class UriString return $host; } - if ('[' !== $host[0] || ']' !== substr($host, -1)) { + if ('[' !== $host[0] || !str_ends_with($host, ']')) { return self::filterRegisteredName($host); } @@ -462,6 +431,6 @@ final class UriString $ip_host = substr($ip_host, 0, $pos); return false !== filter_var($ip_host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) - && 0 === strpos((string) inet_pton($ip_host), self::ZONE_ID_ADDRESS_BLOCK); + && str_starts_with((string)inet_pton($ip_host), self::ZONE_ID_ADDRESS_BLOCK); } } diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriTemplate.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriTemplate.php index ba7a5a33..3a9a3339 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriTemplate.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriTemplate.php @@ -19,7 +19,7 @@ use League\Uri\Exceptions\SyntaxError; use League\Uri\Exceptions\TemplateCanNotBeExpanded; use League\Uri\UriTemplate\Template; use League\Uri\UriTemplate\VariableBag; -use TypeError; +use Stringable; /** * Defines the URI Template syntax and the process for expanding a URI Template into a URI reference. @@ -34,25 +34,22 @@ use TypeError; */ final class UriTemplate { - private Template $template; - private VariableBag $defaultVariables; + public readonly Template $template; + public readonly VariableBag $defaultVariables; /** - * @param object|string $template a string or an object with the __toString method - * - * @throws TypeError if the template is not a string or an object with the __toString method * @throws SyntaxError if the template syntax is invalid * @throws TemplateCanNotBeExpanded if the template variables are invalid */ - public function __construct($template, array $defaultVariables = []) + public function __construct(Template|Stringable|string $template, VariableBag|array $defaultVariables = []) { - $this->template = Template::createFromString($template); + $this->template = $template instanceof Template ? $template : Template::createFromString($template); $this->defaultVariables = $this->filterVariables($defaultVariables); } public static function __set_state(array $properties): self { - return new self($properties['template']->toString(), $properties['defaultVariables']->all()); + return new self($properties['template'], $properties['defaultVariables']); } /** @@ -60,16 +57,19 @@ final class UriTemplate * * @param array> $variables */ - private function filterVariables(array $variables): VariableBag + private function filterVariables(VariableBag|array $variables): VariableBag { - $output = new VariableBag(); - foreach ($this->template->variableNames() as $name) { - if (isset($variables[$name])) { - $output->assign($name, $variables[$name]); - } - } + return array_reduce( + $this->template->variableNames, + function (VariableBag $curry, string $name) use ($variables): VariableBag { + if (isset($variables[$name])) { + $curry[$name] = $variables[$name]; + } - return $output; + return $curry; + }, + new VariableBag() + ); } /** @@ -77,7 +77,7 @@ final class UriTemplate */ public function getTemplate(): string { - return $this->template->toString(); + return $this->template->value; } /** @@ -87,7 +87,7 @@ final class UriTemplate */ public function getVariableNames(): array { - return $this->template->variableNames(); + return $this->template->variableNames; } /** @@ -111,19 +111,16 @@ final class UriTemplate * If present, variables whose name is not part of the current template * possible variable names are removed. */ - public function withDefaultVariables(array $defaultDefaultVariables): self + public function withDefaultVariables(VariableBag|array $defaultDefaultVariables): self { - return new self( - $this->template->toString(), - $this->filterVariables($defaultDefaultVariables)->all() - ); + return new self($this->template, $defaultDefaultVariables); } /** * @throws TemplateCanNotBeExpanded if the variable contains nested array values * @throws UriException if the resulting expansion can not be converted to a UriInterface instance */ - public function expand(array $variables = []): UriInterface + public function expand(VariableBag|array $variables = []): UriInterface { return Uri::createFromString( $this->template->expand( diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriTemplate/Expression.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriTemplate/Expression.php index 99ecac98..0f998f52 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriTemplate/Expression.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriTemplate/Expression.php @@ -16,7 +16,6 @@ namespace League\Uri\UriTemplate; use League\Uri\Exceptions\SyntaxError; use League\Uri\Exceptions\TemplateCanNotBeExpanded; use function array_filter; -use function array_keys; use function array_map; use function array_unique; use function explode; @@ -24,7 +23,6 @@ use function implode; use function preg_match; use function rawurlencode; use function str_replace; -use function strpos; use function substr; final class Expression @@ -64,46 +62,29 @@ final class Expression '&' => ['prefix' => '&', 'joiner' => '&', 'query' => true], ]; - private string $operator; /** @var array */ private array $varSpecifiers; private string $joiner; /** @var array */ - private array $variableNames; - private string $expressionString; + public readonly array $variableNames; + public readonly string $value; - private function __construct(string $operator, VarSpecifier ...$varSpecifiers) + private function __construct(private string $operator, VarSpecifier ...$varSpecifiers) { - $this->operator = $operator; $this->varSpecifiers = $varSpecifiers; $this->joiner = self::OPERATOR_HASH_LOOKUP[$operator]['joiner']; - $this->variableNames = $this->setVariableNames(); - $this->expressionString = $this->setExpressionString(); + $this->variableNames = array_unique(array_map( + static fn (VarSpecifier $varSpecifier): string => $varSpecifier->name, + $varSpecifiers + )); + $this->value = '{'.$operator.implode(',', array_map( + static fn (VarSpecifier $varSpecifier): string => $varSpecifier->toString(), + $varSpecifiers + )).'}'; } /** - * @return array - */ - private function setVariableNames(): array - { - return array_unique(array_map( - static fn (VarSpecifier $varSpecifier): string => $varSpecifier->name(), - $this->varSpecifiers - )); - } - - private function setExpressionString(): string - { - $varSpecifierString = implode(',', array_map( - static fn (VarSpecifier $variable): string => $variable->toString(), - $this->varSpecifiers - )); - - return '{'.$this->operator.$varSpecifierString.'}'; - } - - /** - * {@inheritDoc} + * @param array{operator:string, varSpecifiers:array} $properties */ public static function __set_state(array $properties): self { @@ -123,7 +104,7 @@ final class Expression /** @var array{operator:string, variables:string} $parts */ $parts = $parts + ['operator' => '']; - if ('' !== $parts['operator'] && false !== strpos(self::RESERVED_OPERATOR, $parts['operator'])) { + if ('' !== $parts['operator'] && str_contains(self::RESERVED_OPERATOR, $parts['operator'])) { throw new SyntaxError('The operator used in the expression "'.$expression.'" is reserved.'); } @@ -136,13 +117,18 @@ final class Expression /** * Returns the expression string representation. * + * @deprecated since version 6.6.0 use the readonly property instead + * @codeCoverageIgnore */ public function toString(): string { - return $this->expressionString; + return $this->value; } /** + * @deprecated since version 6.6.0 use the readonly property instead + * @codeCoverageIgnore + * * @return array */ public function variableNames(): array @@ -178,7 +164,7 @@ final class Expression */ private function replace(VarSpecifier $varSpec, VariableBag $variables): string { - $value = $variables->fetch($varSpec->name()); + $value = $variables->fetch($varSpec->name); if (null === $value) { return ''; } @@ -190,10 +176,10 @@ final class Expression } if ('&' !== $this->joiner && '' === $expanded) { - return $varSpec->name(); + return $varSpec->name; } - return $varSpec->name().'='.$expanded; + return $varSpec->name.'='.$expanded; } /** @@ -201,7 +187,7 @@ final class Expression * * @return array{0:string, 1:bool} */ - private function inject($value, VarSpecifier $varSpec, bool $useQuery): array + private function inject(array|string $value, VarSpecifier $varSpec, bool $useQuery): array { if (is_string($value)) { return $this->replaceString($value, $varSpec, $useQuery); @@ -217,16 +203,15 @@ final class Expression */ private function replaceString(string $value, VarSpecifier $varSpec, bool $useQuery): array { - if (':' === $varSpec->modifier()) { - $value = substr($value, 0, $varSpec->position()); + if (':' === $varSpec->modifier) { + $value = substr($value, 0, $varSpec->position); } - $expanded = rawurlencode($value); - if ('+' === $this->operator || '#' === $this->operator) { - return [$this->decodeReserved($expanded), $useQuery]; + if (in_array($this->operator, ['+', '#'], true)) { + return [$this->decodeReserved(rawurlencode($value)), $useQuery]; } - return [$expanded, $useQuery]; + return [rawurlencode($value), $useQuery]; } /** @@ -244,48 +229,45 @@ final class Expression return ['', false]; } - if (':' === $varSpec->modifier()) { - throw TemplateCanNotBeExpanded::dueToUnableToProcessValueListWithPrefix($varSpec->name()); + if (':' === $varSpec->modifier) { + throw TemplateCanNotBeExpanded::dueToUnableToProcessValueListWithPrefix($varSpec->name); } $pairs = []; - $isAssoc = $this->isAssoc($value); + $isList = array_is_list($value); foreach ($value as $key => $var) { - if ($isAssoc) { + if (!$isList) { $key = rawurlencode((string) $key); } $var = rawurlencode($var); - if ('+' === $this->operator || '#' === $this->operator) { + if (in_array($this->operator, ['+', '#'], true)) { $var = $this->decodeReserved($var); } - if ('*' === $varSpec->modifier()) { - if ($isAssoc) { + if ('*' === $varSpec->modifier) { + if (!$isList) { $var = $key.'='.$var; } elseif ($key > 0 && $useQuery) { - $var = $varSpec->name().'='.$var; + $var = $varSpec->name.'='.$var; } } $pairs[$key] = $var; } - if ('*' === $varSpec->modifier()) { - if ($isAssoc) { - // Don't prepend the value name when using the explode - // modifier with an associative array. + if ('*' === $varSpec->modifier) { + if (!$isList) { + // Don't prepend the value name when using the `explode` modifier with an associative array. $useQuery = false; } return [implode($this->joiner, $pairs), $useQuery]; } - if ($isAssoc) { - // When an associative array is encountered and the - // explode modifier is not set, then the result must be - // a comma separated list of keys followed by their - // respective values. + if (!$isList) { + // When an associative array is encountered and the `explode` modifier is not set, then + // the result must be a comma separated list of keys followed by their respective values. foreach ($pairs as $offset => &$data) { $data = $offset.','.$data; } @@ -296,19 +278,6 @@ final class Expression return [implode(',', $pairs), $useQuery]; } - /** - * Determines if an array is associative. - * - * This makes the assumption that input arrays are sequences or hashes. - * This assumption is a trade-off for accuracy in favor of speed, but it - * should work in almost every case where input is supplied for a URI - * template. - */ - private function isAssoc(array $array): bool - { - return [] !== $array && 0 !== array_keys($array)[0]; - } - /** * Removes percent encoding on reserved characters (used with + and # modifiers). */ diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriTemplate/Template.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriTemplate/Template.php index ecd130fe..826bcbc5 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriTemplate/Template.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriTemplate/Template.php @@ -15,17 +15,11 @@ namespace League\Uri\UriTemplate; use League\Uri\Exceptions\SyntaxError; use League\Uri\Exceptions\TemplateCanNotBeExpanded; -use TypeError; -use function array_merge; +use Stringable; use function array_unique; -use function gettype; -use function is_object; -use function is_string; -use function method_exists; use function preg_match_all; use function preg_replace; -use function sprintf; -use function strpos; +use function str_contains; use const PREG_SET_ORDER; final class Template @@ -33,53 +27,42 @@ final class Template /** * Expression regular expression pattern. */ - private const REGEXP_EXPRESSION_DETECTOR = '/\{[^\}]*\}/x'; + private const REGEXP_EXPRESSION_DETECTOR = '/\{[^}]*}/x'; - private string $template; /** @var array */ private array $expressions = []; /** @var array */ - private array $variableNames; + public readonly array $variableNames; - private function __construct(string $template, Expression ...$expressions) + private function __construct(public readonly string $value, Expression ...$expressions) { - $this->template = $template; $variableNames = []; foreach ($expressions as $expression) { - $this->expressions[$expression->toString()] = $expression; - $variableNames[] = $expression->variableNames(); + $this->expressions[$expression->value] = $expression; + $variableNames = [...$variableNames, ...$expression->variableNames]; } - $this->variableNames = array_unique(array_merge([], ...$variableNames)); + + $this->variableNames = array_unique($variableNames); } /** - * {@inheritDoc} + * @param array{value:string, template?:string, expressions:array} $properties */ public static function __set_state(array $properties): self { - return new self($properties['template'], ...array_values($properties['expressions'])); + return new self($properties['template'] ?? $properties['value'], ...array_values($properties['expressions'])); } /** - * @param object|string $template a string or an object with the __toString method - * - * @throws TypeError if the template is not a string or an object with the __toString method * @throws SyntaxError if the template contains invalid expressions * @throws SyntaxError if the template contains invalid variable specification */ - public static function createFromString($template): self + public static function createFromString(Stringable|string $template): self { - if (is_object($template) && method_exists($template, '__toString')) { - $template = (string) $template; - } - - if (!is_string($template)) { - throw new TypeError(sprintf('The template must be a string or a stringable object %s given.', gettype($template))); - } - + $template = (string) $template; /** @var string $remainder */ $remainder = preg_replace(self::REGEXP_EXPRESSION_DETECTOR, '', $template); - if (false !== strpos($remainder, '{') || false !== strpos($remainder, '}')) { + if (str_contains($remainder, '{') || str_contains($remainder, '}')) { throw new SyntaxError('The template "'.$template.'" contains invalid expressions.'); } @@ -96,12 +79,19 @@ final class Template return new self($template, ...$arguments); } + /** + * @deprecated since version 6.6.0 use the readonly property instead + * @codeCoverageIgnore + */ public function toString(): string { - return $this->template; + return $this->value; } /** + * @deprecated since version 6.6.0 use the readonly property instead + * @codeCoverageIgnore + * * @return array */ public function variableNames(): array @@ -115,7 +105,7 @@ final class Template */ public function expand(VariableBag $variables): string { - $uriString = $this->template; + $uriString = $this->value; /** @var Expression $expression */ foreach ($this->expressions as $pattern => $expression) { $uriString = str_replace($pattern, $expression->expand($variables), $uriString); diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriTemplate/VarSpecifier.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriTemplate/VarSpecifier.php index ac49efb5..0827a0a8 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriTemplate/VarSpecifier.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriTemplate/VarSpecifier.php @@ -28,19 +28,15 @@ final class VarSpecifier (?\:(?\d+)|\*)? $/x'; - private string $name; - private string $modifier; - private int $position; - - private function __construct(string $name, string $modifier, int $position) - { - $this->name = $name; - $this->modifier = $modifier; - $this->position = $position; + private function __construct( + public readonly string $name, + public readonly string $modifier, + public readonly int $position + ) { } /** - * {@inheritDoc} + * @param array{name: string, modifier:string, position:int} $properties */ public static function __set_state(array $properties): self { @@ -79,16 +75,28 @@ final class VarSpecifier return $this->name.$this->modifier; } + /** + * @codeCoverageIgnore + * @deprecated since version 6.6.0 use the readonly property instead + */ public function name(): string { return $this->name; } + /** + * @codeCoverageIgnore + * @deprecated since version 6.6.0 use the readonly property instead + */ public function modifier(): string { return $this->modifier; } + /** + * @codeCoverageIgnore + * @deprecated since version 6.6.0 use the readonly property instead + */ public function position(): int { return $this->position; diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriTemplate/VariableBag.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriTemplate/VariableBag.php index cf60de91..a3e559dd 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriTemplate/VariableBag.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/league/uri/src/UriTemplate/VariableBag.php @@ -13,17 +13,18 @@ declare(strict_types=1); namespace League\Uri\UriTemplate; +use ArrayAccess; +use Countable; use League\Uri\Exceptions\TemplateCanNotBeExpanded; -use TypeError; -use function gettype; -use function is_array; +use Stringable; use function is_bool; use function is_object; use function is_scalar; -use function method_exists; -use function sprintf; -final class VariableBag +/** + * @implements ArrayAccess> + */ +final class VariableBag implements ArrayAccess, Countable { /** * @var array> @@ -40,11 +41,39 @@ final class VariableBag } } + public function count(): int + { + return count($this->variables); + } + + /** + * @param array{variables: array>} $properties + */ public static function __set_state(array $properties): self { return new self($properties['variables']); } + public function offsetExists(mixed $offset): bool + { + return array_key_exists($offset, $this->variables); + } + + public function offsetUnset(mixed $offset): void + { + unset($this->variables[$offset]); + } + + public function offsetSet(mixed $offset, mixed $value): void + { + $this->assign($offset, $value); /* @phpstan-ignore-line */ + } + + public function offsetGet(mixed $offset): mixed + { + return $this->fetch($offset); + } + /** * @return array> */ @@ -53,55 +82,45 @@ final class VariableBag return $this->variables; } + /** + * Tells whether the bag is empty or not. + */ + public function isEmpty(): bool + { + return [] === $this->variables; + } + /** * Fetches the variable value if none found returns null. * * @return null|string|array */ - public function fetch(string $name) + public function fetch(string $name): null|string|array { return $this->variables[$name] ?? null; } /** - * @param string|bool|int|float|array $value + * @param string|bool|int|float|null|array $value */ - public function assign(string $name, $value): void + public function assign(string $name, string|bool|int|float|array|null $value): void { $this->variables[$name] = $this->normalizeValue($value, $name, true); } /** - * @param mixed $value the value to be expanded + * @param Stringable|string|float|int|bool|null $value the value to be expanded * * @throws TemplateCanNotBeExpanded if the value contains nested list - * - * @return string|array */ - private function normalizeValue($value, string $name, bool $isNestedListAllowed) + private function normalizeValue(Stringable|array|string|float|int|bool|null $value, string $name, bool $isNestedListAllowed): array|string { - if (is_bool($value)) { - return true === $value ? '1' : '0'; - } - - if (null === $value || is_scalar($value) || (is_object($value) && method_exists($value, '__toString'))) { - return (string) $value; - } - - if (!is_array($value)) { - throw new TypeError(sprintf('The variable '.$name.' must be NULL, a scalar or a stringable object `%s` given', gettype($value))); - } - - if (!$isNestedListAllowed) { - throw TemplateCanNotBeExpanded::dueToNestedListOfValue($name); - } - - foreach ($value as &$var) { - $var = self::normalizeValue($var, $name, false); - } - unset($var); - - return $value; + return match (true) { + is_bool($value) => true === $value ? '1' : '0', + (null === $value || is_scalar($value) || is_object($value)) => (string) $value, + !$isNestedListAllowed => throw TemplateCanNotBeExpanded::dueToNestedListOfValue($name), + default => array_map(fn ($var): array|string => self::normalizeValue($var, $name, false), $value), + }; } /** diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/.php-cs-fixer.dist.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/.php-cs-fixer.dist.php deleted file mode 100644 index 04765dec..00000000 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/.php-cs-fixer.dist.php +++ /dev/null @@ -1,25 +0,0 @@ -in(__DIR__.'/src') - ->in(__DIR__.'/tests'); - -$config = new PhpCsFixer\Config(); - -return $config->setRules([ - '@Symfony' => true, - '@Symfony:risky' => true, - 'native_function_invocation' => ['include'=> ['@all']], - 'native_constant_invocation' => true, - 'ordered_imports' => true, - 'declare_strict_types' => false, - 'linebreak_after_opening_tag' => false, - 'single_import_per_statement' => false, - 'blank_line_after_opening_tag' => false, - 'concat_space' => ['spacing'=>'one'], - 'phpdoc_align' => ['align'=>'left'], -]) - ->setRiskyAllowed(true) - ->setFinder($finder); diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/CHANGELOG.md b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/CHANGELOG.md index cddd3633..17a819fb 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/CHANGELOG.md +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file, in reverse chronological order by release. +## 1.8.2 + +- Fix deprecation warnings in PHP 8.4 + +## 1.8.1 + +- Fix error handling in Stream::getContents() + ## 1.8.0 - Deprecate HttplugFactory, use Psr17Factory instead diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/phpstan-baseline.neon b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/phpstan-baseline.neon deleted file mode 100644 index 9a0cf115..00000000 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/phpstan-baseline.neon +++ /dev/null @@ -1,36 +0,0 @@ -parameters: - ignoreErrors: - - - message: "#^Result of && is always false\\.$#" - count: 1 - path: src/Response.php - - - - message: "#^Strict comparison using \\=\\=\\= between null and string will always evaluate to false\\.$#" - count: 1 - path: src/Response.php - - - - message: "#^Result of && is always false\\.$#" - count: 1 - path: src/ServerRequest.php - - - - message: "#^Strict comparison using \\!\\=\\= between null and null will always evaluate to false\\.$#" - count: 1 - path: src/ServerRequest.php - - - - message: "#^Result of && is always false\\.$#" - count: 1 - path: src/Stream.php - - - - message: "#^Result of && is always false\\.$#" - count: 2 - path: src/UploadedFile.php - - - - message: "#^Strict comparison using \\=\\=\\= between false and true will always evaluate to false\\.$#" - count: 2 - path: src/UploadedFile.php diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/psalm.baseline.xml b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/psalm.baseline.xml deleted file mode 100644 index fe5b92e7..00000000 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/psalm.baseline.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - return \trigger_error((string) $e, \E_USER_ERROR); - - - diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/src/Factory/Psr17Factory.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/src/Factory/Psr17Factory.php index 440bec34..2fa98bee 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/src/Factory/Psr17Factory.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/src/Factory/Psr17Factory.php @@ -57,7 +57,7 @@ class Psr17Factory implements RequestFactoryInterface, ResponseFactoryInterface, return Stream::create($resource); } - public function createUploadedFile(StreamInterface $stream, int $size = null, int $error = \UPLOAD_ERR_OK, string $clientFilename = null, string $clientMediaType = null): UploadedFileInterface + public function createUploadedFile(StreamInterface $stream, ?int $size = null, int $error = \UPLOAD_ERR_OK, ?string $clientFilename = null, ?string $clientMediaType = null): UploadedFileInterface { if (null === $size) { $size = $stream->getSize(); diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/src/Response.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/src/Response.php index f3e20978..71eb2fa4 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/src/Response.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/src/Response.php @@ -39,7 +39,7 @@ class Response implements ResponseInterface * @param string $version Protocol version * @param string|null $reason Reason phrase (when empty a default will be used based on the status code) */ - public function __construct(int $status = 200, array $headers = [], $body = null, string $version = '1.1', string $reason = null) + public function __construct(int $status = 200, array $headers = [], $body = null, string $version = '1.1', ?string $reason = null) { // If we got no body, defer initialization of the stream until Response::getBody() if ('' !== $body && null !== $body) { diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/src/Stream.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/src/Stream.php index d3bd78d1..63b7d6dd 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/src/Stream.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/nyholm/psr7/src/Stream.php @@ -260,11 +260,19 @@ class Stream implements StreamInterface throw new \RuntimeException('Stream is detached'); } - if (false === $contents = @\stream_get_contents($this->stream)) { - throw new \RuntimeException('Unable to read stream contents: ' . (\error_get_last()['message'] ?? '')); - } + $exception = null; - return $contents; + \set_error_handler(static function ($type, $message) use (&$exception) { + throw $exception = new \RuntimeException('Unable to read stream contents: ' . $message); + }); + + try { + return \stream_get_contents($this->stream); + } catch (\Throwable $e) { + throw $e === $exception ? $e : new \RuntimeException('Unable to read stream contents: ' . $e->getMessage(), 0, $e); + } finally { + \restore_error_handler(); + } } /** diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/psr/http-client/CHANGELOG.md b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/psr/http-client/CHANGELOG.md index e2dc25f5..babba7c7 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/psr/http-client/CHANGELOG.md +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/psr/http-client/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file, in reverse chronological order by release. +## 1.0.3 + +Add `source` link in composer.json. No code changes. + +## 1.0.2 + +Allow PSR-7 (psr/http-message) 2.0. No code changes. + ## 1.0.1 Allow installation with PHP 8. No code changes. diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/psr/http-client/README.md b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/psr/http-client/README.md index 6876b840..84af5c55 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/psr/http-client/README.md +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/psr/http-client/README.md @@ -7,6 +7,6 @@ Note that this is not a HTTP Client implementation of its own. It is merely abst The installable [package][package-url] and [implementations][implementation-url] are listed on Packagist. -[psr-url]: http://www.php-fig.org/psr/psr-18 +[psr-url]: https://www.php-fig.org/psr/psr-18 [package-url]: https://packagist.org/packages/psr/http-client [implementation-url]: https://packagist.org/providers/psr/http-client-implementation diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/psr/http-client/composer.json b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/psr/http-client/composer.json index c195f8ff..6fed350b 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/psr/http-client/composer.json +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/psr/http-client/composer.json @@ -7,12 +7,15 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, "require": { "php": "^7.0 || ^8.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0 || ^2.0" }, "autoload": { "psr-4": { diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-ctype/LICENSE b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-ctype/LICENSE index 3f853aaf..7536caea 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-ctype/LICENSE +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-ctype/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2018-2019 Fabien Potencier +Copyright (c) 2018-present Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-ctype/composer.json b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-ctype/composer.json index 1b3efff5..131ca7ad 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-ctype/composer.json +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-ctype/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" @@ -30,9 +30,6 @@ }, "minimum-stability": "dev", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php80/LICENSE b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php80/LICENSE index 5593b1d8..0ed3a246 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php80/LICENSE +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php80/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020 Fabien Potencier +Copyright (c) 2020-present Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php80/composer.json b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php80/composer.json index bd9a3262..a503b039 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php80/composer.json +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php80/composer.json @@ -20,7 +20,7 @@ } ], "require": { - "php": ">=7.1" + "php": ">=7.2" }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Php80\\": "" }, @@ -29,9 +29,6 @@ }, "minimum-stability": "dev", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php81/LICENSE b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php81/LICENSE index efb17f98..99c6bdf3 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php81/LICENSE +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php81/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021 Fabien Potencier +Copyright (c) 2021-present Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php81/README.md b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php81/README.md index 7d8dd190..c07ef782 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php81/README.md +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php81/README.md @@ -7,6 +7,7 @@ This component provides features added to PHP 8.1 core: - [`enum_exists`](https://php.net/enum-exists) - [`MYSQLI_REFRESH_REPLICA`](https://php.net/mysqli.constants#constantmysqli-refresh-replica) constant - [`ReturnTypeWillChange`](https://wiki.php.net/rfc/internal_method_return_types) +- [`CURLStringFile`](https://php.net/CURLStringFile) (but only if PHP >= 7.4 is used) More information can be found in the [main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php new file mode 100644 index 00000000..5ff93fca --- /dev/null +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (\PHP_VERSION_ID >= 70400 && extension_loaded('curl')) { + /** + * @property string $data + */ + class CURLStringFile extends CURLFile + { + private $data; + + public function __construct(string $data, string $postname, string $mime = 'application/octet-stream') + { + $this->data = $data; + parent::__construct('data://application/octet-stream;base64,'.base64_encode($data), $mime, $postname); + } + + public function __set(string $name, $value): void + { + if ('data' !== $name) { + $this->$name = $value; + + return; + } + + if (is_object($value) ? !method_exists($value, '__toString') : !is_scalar($value)) { + throw new TypeError('Cannot assign '.gettype($value).' to property CURLStringFile::$data of type string'); + } + + $this->name = 'data://application/octet-stream;base64,'.base64_encode($value); + } + + public function __isset(string $name): bool + { + return isset($this->$name); + } + + public function &__get(string $name) + { + return $this->$name; + } + } +} diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php81/composer.json b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php81/composer.json index 149b5982..381af79a 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php81/composer.json +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/polyfill-php81/composer.json @@ -25,9 +25,6 @@ }, "minimum-stability": "dev", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/ExecutableFinder.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/ExecutableFinder.php index eb8f0629..f392c962 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/ExecutableFinder.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/ExecutableFinder.php @@ -46,7 +46,7 @@ class ExecutableFinder * * @return string|null */ - public function find(string $name, string $default = null, array $extraDirs = []) + public function find(string $name, ?string $default = null, array $extraDirs = []) { if (\ini_get('open_basedir')) { $searchPath = array_merge(explode(\PATH_SEPARATOR, \ini_get('open_basedir')), $extraDirs); diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/InputStream.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/InputStream.php index 240665f3..0c45b524 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/InputStream.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/InputStream.php @@ -30,7 +30,7 @@ class InputStream implements \IteratorAggregate /** * Sets a callback that is called when the write buffer becomes empty. */ - public function onEmpty(callable $onEmpty = null) + public function onEmpty(?callable $onEmpty = null) { $this->onEmpty = $onEmpty; } diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/PhpExecutableFinder.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/PhpExecutableFinder.php index bed6c3dc..45dbcca4 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/PhpExecutableFinder.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/PhpExecutableFinder.php @@ -35,7 +35,7 @@ class PhpExecutableFinder { if ($php = getenv('PHP_BINARY')) { if (!is_executable($php)) { - $command = '\\' === \DIRECTORY_SEPARATOR ? 'where' : 'command -v'; + $command = '\\' === \DIRECTORY_SEPARATOR ? 'where' : 'command -v --'; if ($php = strtok(exec($command.' '.escapeshellarg($php)), \PHP_EOL)) { if (!is_executable($php)) { return false; diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/PhpProcess.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/PhpProcess.php index 2bc338e5..3a1d147c 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/PhpProcess.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/PhpProcess.php @@ -32,7 +32,7 @@ class PhpProcess extends Process * @param int $timeout The timeout in seconds * @param array|null $php Path to the PHP binary to use with any additional arguments */ - public function __construct(string $script, string $cwd = null, array $env = null, int $timeout = 60, array $php = null) + public function __construct(string $script, ?string $cwd = null, ?array $env = null, int $timeout = 60, ?array $php = null) { if (null === $php) { $executableFinder = new PhpExecutableFinder(); @@ -53,7 +53,7 @@ class PhpProcess extends Process /** * {@inheritdoc} */ - public static function fromShellCommandline(string $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60) + public static function fromShellCommandline(string $command, ?string $cwd = null, ?array $env = null, $input = null, ?float $timeout = 60) { throw new LogicException(sprintf('The "%s()" method cannot be called when using "%s".', __METHOD__, self::class)); } @@ -61,7 +61,7 @@ class PhpProcess extends Process /** * {@inheritdoc} */ - public function start(callable $callback = null, array $env = []) + public function start(?callable $callback = null, array $env = []) { if (null === $this->getCommandLine()) { throw new RuntimeException('Unable to find the PHP executable.'); diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/Pipes/WindowsPipes.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/Pipes/WindowsPipes.php index bca84f57..968dd026 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/Pipes/WindowsPipes.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/Pipes/WindowsPipes.php @@ -149,7 +149,7 @@ class WindowsPipes extends AbstractPipes if ($w) { @stream_select($r, $w, $e, 0, Process::TIMEOUT_PRECISION * 1E6); } elseif ($this->fileHandles) { - usleep(Process::TIMEOUT_PRECISION * 1E6); + usleep((int) (Process::TIMEOUT_PRECISION * 1E6)); } } foreach ($this->fileHandles as $type => $fileHandle) { diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/Process.php b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/Process.php index 30ebeb6b..a4b0a784 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/Process.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn-vendor/symfony/process/Process.php @@ -80,6 +80,7 @@ class Process implements \IteratorAggregate private $processPipes; private $latestSignal; + private $cachedExitCode; private static $sigchild; @@ -140,7 +141,7 @@ class Process implements \IteratorAggregate * * @throws LogicException When proc_open is not installed */ - public function __construct(array $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60) + public function __construct(array $command, ?string $cwd = null, ?array $env = null, $input = null, ?float $timeout = 60) { if (!\function_exists('proc_open')) { throw new LogicException('The Process class relies on proc_open, which is not available on your PHP installation.'); @@ -189,7 +190,7 @@ class Process implements \IteratorAggregate * * @throws LogicException When proc_open is not installed */ - public static function fromShellCommandline(string $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60) + public static function fromShellCommandline(string $command, ?string $cwd = null, ?array $env = null, $input = null, ?float $timeout = 60) { $process = new static([], $cwd, $env, $input, $timeout); $process->commandline = $command; @@ -247,7 +248,7 @@ class Process implements \IteratorAggregate * * @final */ - public function run(callable $callback = null, array $env = []): int + public function run(?callable $callback = null, array $env = []): int { $this->start($callback, $env); @@ -266,7 +267,7 @@ class Process implements \IteratorAggregate * * @final */ - public function mustRun(callable $callback = null, array $env = []): self + public function mustRun(?callable $callback = null, array $env = []): self { if (0 !== $this->run($callback, $env)) { throw new ProcessFailedException($this); @@ -294,7 +295,7 @@ class Process implements \IteratorAggregate * @throws RuntimeException When process is already running * @throws LogicException In case a callback is provided and output has been disabled */ - public function start(callable $callback = null, array $env = []) + public function start(?callable $callback = null, array $env = []) { if ($this->isRunning()) { throw new RuntimeException('Process is already running.'); @@ -385,7 +386,7 @@ class Process implements \IteratorAggregate * * @final */ - public function restart(callable $callback = null, array $env = []): self + public function restart(?callable $callback = null, array $env = []): self { if ($this->isRunning()) { throw new RuntimeException('Process is already running.'); @@ -412,7 +413,7 @@ class Process implements \IteratorAggregate * @throws ProcessSignaledException When process stopped after receiving signal * @throws LogicException When process is not yet started */ - public function wait(callable $callback = null) + public function wait(?callable $callback = null) { $this->requireProcessIsStarted(__FUNCTION__); @@ -914,7 +915,7 @@ class Process implements \IteratorAggregate * * @return int|null The exit-code of the process or null if it's not running */ - public function stop(float $timeout = 10, int $signal = null) + public function stop(float $timeout = 10, ?int $signal = null) { $timeoutMicro = microtime(true) + $timeout; if ($this->isRunning()) { @@ -1310,7 +1311,7 @@ class Process implements \IteratorAggregate * * @return \Closure */ - protected function buildCallback(callable $callback = null) + protected function buildCallback(?callable $callback = null) { if ($this->outputDisabled) { return function ($type, $data) use ($callback): bool { @@ -1345,6 +1346,19 @@ class Process implements \IteratorAggregate $this->processInformation = proc_get_status($this->process); $running = $this->processInformation['running']; + // In PHP < 8.3, "proc_get_status" only returns the correct exit status on the first call. + // Subsequent calls return -1 as the process is discarded. This workaround caches the first + // retrieved exit status for consistent results in later calls, mimicking PHP 8.3 behavior. + if (\PHP_VERSION_ID < 80300) { + if (!isset($this->cachedExitCode) && !$running && -1 !== $this->processInformation['exitcode']) { + $this->cachedExitCode = $this->processInformation['exitcode']; + } + + if (isset($this->cachedExitCode) && !$running && -1 === $this->processInformation['exitcode']) { + $this->processInformation['exitcode'] = $this->cachedExitCode; + } + } + $this->readPipes($running && $blocking, '\\' !== \DIRECTORY_SEPARATOR || !$running); if ($this->fallbackStatus && $this->isSigchildEnabled()) { diff --git a/wp-content/plugins/wp-webauthn/wp-webauthn.php b/wp-content/plugins/wp-webauthn/wp-webauthn.php index cfeabab8..ae962256 100644 --- a/wp-content/plugins/wp-webauthn/wp-webauthn.php +++ b/wp-content/plugins/wp-webauthn/wp-webauthn.php @@ -3,7 +3,7 @@ Plugin Name: WP-WebAuthn Plugin URI: https://flyhigher.top Description: WP-WebAuthn allows you to safely login to your WordPress site without password. -Version: 1.3.1 +Version: 1.3.4 Author: Axton Author URI: https://axton.cc License: GPLv3 @@ -20,7 +20,7 @@ You should have received a copy of the GNU General Public License along with thi register_activation_hook(__FILE__, 'wwa_init'); function wwa_init(){ - if(version_compare(get_bloginfo('version'), '4.4', '<')){ + if(version_compare(get_bloginfo('version'), '5.0', '<')){ deactivate_plugins(basename(__FILE__)); //disable }else{ wwa_init_data(); @@ -32,7 +32,7 @@ wwa_init_data(); function wwa_init_data(){ if(!get_option('wwa_init')){ // Init - $site_domain = parse_url(site_url(), PHP_URL_HOST); + $site_domain = wp_parse_url(site_url(), PHP_URL_HOST); $wwa_init_options = array( 'user_credentials' => '{}', 'user_credentials_meta' => '{}', @@ -53,7 +53,7 @@ function wwa_init_data(){ include('wwa-version.php'); update_option('wwa_version', $wwa_version); update_option('wwa_log', array()); - update_option('wwa_init', md5(date('Y-m-d H:i:s'))); + update_option('wwa_init', md5(date('Y-m-d H:i:s'))); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date }else{ include('wwa-version.php'); if(!get_option('wwa_version') || get_option('wwa_version')['version'] != $wwa_version['version']){ @@ -83,4 +83,3 @@ include('wwa-menus.php'); include('wwa-functions.php'); include('wwa-ajax.php'); include('wwa-shortcodes.php'); -?> \ No newline at end of file diff --git a/wp-content/plugins/wp-webauthn/wwa-admin-content.php b/wp-content/plugins/wp-webauthn/wwa-admin-content.php index 8053e3cb..c5fb7f99 100644 --- a/wp-content/plugins/wp-webauthn/wwa-admin-content.php +++ b/wp-content/plugins/wp-webauthn/wwa-admin-content.php @@ -24,7 +24,7 @@ if(!function_exists('sodium_crypto_sign_detached')){ add_settings_error('wwa_settings', 'sodium_error', __("PHP extension sodium doesn't seem to exist, rendering WP-WebAuthn unable to function.", 'wp-webauthn')); $wwa_not_allowed = true; } -if(!wwa_check_ssl() && (parse_url(site_url(), PHP_URL_HOST) !== 'localhost' && parse_url(site_url(), PHP_URL_HOST) !== '127.0.0.1')){ +if(!wwa_check_ssl() && (wp_parse_url(site_url(), PHP_URL_HOST) !== 'localhost' && wp_parse_url(site_url(), PHP_URL_HOST) !== '127.0.0.1')){ add_settings_error('wwa_settings', 'https_error', __('WebAuthn features are restricted to websites in secure contexts. Please make sure your website is served over HTTPS or locally with localhost.', 'wp-webauthn')); $wwa_not_allowed = true; } @@ -33,18 +33,22 @@ if( (isset($_POST['wwa_ref']) && $_POST['wwa_ref'] === 'true') && check_admin_referer('wwa_options_update') && wwa_validate_privileges() - && ($_POST['first_choice'] === 'true' || $_POST['first_choice'] === 'false' || $_POST['first_choice'] === 'webauthn') - && ($_POST['remember_me'] === 'true' || $_POST['remember_me'] === 'false') - && ($_POST['email_login'] === 'true' || $_POST['email_login'] === 'false') - && ($_POST['user_verification'] === 'true' || $_POST['user_verification'] === 'false') - && ($_POST['usernameless_login'] === 'true' || $_POST['usernameless_login'] === 'false') - && ($_POST['allow_authenticator_type'] === 'none' || $_POST['allow_authenticator_type'] === 'platform' || $_POST['allow_authenticator_type'] === 'cross-platform') - && ($_POST['password_reset'] === 'off' || $_POST['password_reset'] === 'admin' || $_POST['password_reset'] === 'all') - && ($_POST['after_user_registration'] === 'none' || $_POST['after_user_registration'] === 'login') - && ($_POST['logging'] === 'true' || $_POST['logging'] === 'false') + && (isset($_POST['first_choice']) && ($_POST['first_choice'] === 'true' || $_POST['first_choice'] === 'false' || $_POST['first_choice'] === 'webauthn')) + && (isset($_POST['remember_me']) && ($_POST['remember_me'] === 'true' || $_POST['remember_me'] === 'false')) + && (isset($_POST['email_login']) && ($_POST['email_login'] === 'true' || $_POST['email_login'] === 'false')) + && (isset($_POST['user_verification']) && ($_POST['user_verification'] === 'true' || $_POST['user_verification'] === 'false')) + && (isset($_POST['usernameless_login']) && ($_POST['usernameless_login'] === 'true' || $_POST['usernameless_login'] === 'false')) + && (isset($_POST['allow_authenticator_type']) && ($_POST['allow_authenticator_type'] === 'none' || $_POST['allow_authenticator_type'] === 'platform' || $_POST['allow_authenticator_type'] === 'cross-platform')) + && (isset($_POST['password_reset']) && ($_POST['password_reset'] === 'off' || $_POST['password_reset'] === 'admin' || $_POST['password_reset'] === 'all')) + && (isset($_POST['after_user_registration']) && ($_POST['after_user_registration'] === 'none' || $_POST['after_user_registration'] === 'login')) + && (isset($_POST['logging']) && ($_POST['logging'] === 'true' || $_POST['logging'] === 'false')) + && isset($_POST['website_name']) + && isset($_POST['website_domain']) ){ $res_id = wwa_generate_random_string(5); - if(sanitize_text_field($_POST['logging']) === 'true' && wwa_get_option('logging') === 'false'){ + + $post_logging = sanitize_text_field(wp_unslash($_POST['logging'])); + if($post_logging === 'true' && wwa_get_option('logging') === 'false'){ // Initialize log if(!function_exists('gmp_intval')){ wwa_add_log($res_id, 'Warning: PHP extension gmp not found', true); @@ -55,70 +59,70 @@ if( if(!function_exists('sodium_crypto_sign_detached')){ wwa_add_log($res_id, 'Warning: PHP extension sodium not found', true); } - if(!wwa_check_ssl() && (parse_url(site_url(), PHP_URL_HOST) !== 'localhost' && parse_url(site_url(), PHP_URL_HOST) !== '127.0.0.1')){ + if(!wwa_check_ssl() && (wp_parse_url(site_url(), PHP_URL_HOST) !== 'localhost' && wp_parse_url(site_url(), PHP_URL_HOST) !== '127.0.0.1')){ wwa_add_log($res_id, 'Warning: Not in security context', true); } wwa_add_log($res_id, 'PHP Version => '.phpversion().', WordPress Version => '.get_bloginfo('version').', WP-WebAuthn Version => '.get_option('wwa_version')['version'], true); wwa_add_log($res_id, 'Current config: first_choice => "'.wwa_get_option('first_choice').'", website_name => "'.wwa_get_option('website_name').'", website_domain => "'.wwa_get_option('website_domain').'", remember_me => "'.wwa_get_option('remember_me').'", email_login => "'.wwa_get_option('email_login').'", user_verification => "'.wwa_get_option('user_verification').'", allow_authenticator_type => "'.wwa_get_option('allow_authenticator_type').'", usernameless_login => "'.wwa_get_option('usernameless_login').'", password_reset => "'.wwa_get_option('password_reset').'", after_user_registration => "'.wwa_get_option('after_user_registration').'"', true); wwa_add_log($res_id, 'Logger initialized', true); } - wwa_update_option('logging', sanitize_text_field($_POST['logging'])); + wwa_update_option('logging', $post_logging); - $post_first_choice = sanitize_text_field($_POST['first_choice']); + $post_first_choice = sanitize_text_field(wp_unslash($_POST['first_choice'])); if($post_first_choice !== wwa_get_option('first_choice')){ wwa_add_log($res_id, 'first_choice: "'.wwa_get_option('first_choice').'"->"'.$post_first_choice.'"'); } wwa_update_option('first_choice', $post_first_choice); - $post_website_name = sanitize_text_field($_POST['website_name']); + $post_website_name = sanitize_text_field(wp_unslash($_POST['website_name'])); if($post_website_name !== wwa_get_option('website_name')){ wwa_add_log($res_id, 'website_name: "'.wwa_get_option('website_name').'"->"'.$post_website_name.'"'); } wwa_update_option('website_name', $post_website_name); - $post_website_domain = str_replace('https:', '', str_replace('/', '', sanitize_text_field($_POST['website_domain']))); + $post_website_domain = str_replace('https:', '', str_replace('/', '', sanitize_text_field(wp_unslash($_POST['website_domain'])))); if($post_website_domain !== wwa_get_option('website_domain')){ wwa_add_log($res_id, 'website_domain: "'.wwa_get_option('website_domain').'"->"'.$post_website_domain.'"'); } wwa_update_option('website_domain', $post_website_domain); - $post_remember_me = sanitize_text_field($_POST['remember_me']); + $post_remember_me = sanitize_text_field(wp_unslash($_POST['remember_me'])); if($post_remember_me !== wwa_get_option('remember_me')){ wwa_add_log($res_id, 'remember_me: "'.wwa_get_option('remember_me').'"->"'.$post_remember_me.'"'); } wwa_update_option('remember_me', $post_remember_me); - $post_email_login = sanitize_text_field($_POST['email_login']); + $post_email_login = sanitize_text_field(wp_unslash($_POST['email_login'])); if($post_email_login !== wwa_get_option('email_login')){ wwa_add_log($res_id, 'email_login: "'.wwa_get_option('email_login').'"->"'.$post_email_login.'"'); } wwa_update_option('email_login', $post_email_login); - $post_user_verification = sanitize_text_field($_POST['user_verification']); + $post_user_verification = sanitize_text_field(wp_unslash($_POST['user_verification'])); if($post_user_verification !== wwa_get_option('user_verification')){ wwa_add_log($res_id, 'user_verification: "'.wwa_get_option('user_verification').'"->"'.$post_user_verification.'"'); } wwa_update_option('user_verification', $post_user_verification); - $post_allow_authenticator_type = sanitize_text_field($_POST['allow_authenticator_type']); + $post_allow_authenticator_type = sanitize_text_field(wp_unslash($_POST['allow_authenticator_type'])); if($post_allow_authenticator_type !== wwa_get_option('allow_authenticator_type')){ wwa_add_log($res_id, 'allow_authenticator_type: "'.wwa_get_option('allow_authenticator_type').'"->"'.$post_allow_authenticator_type.'"'); } wwa_update_option('allow_authenticator_type', $post_allow_authenticator_type); - $post_usernameless_login = sanitize_text_field($_POST['usernameless_login']); + $post_usernameless_login = sanitize_text_field(wp_unslash($_POST['usernameless_login'])); if($post_usernameless_login !== wwa_get_option('usernameless_login')){ wwa_add_log($res_id, 'usernameless_login: "'.wwa_get_option('usernameless_login').'"->"'.$post_usernameless_login.'"'); } wwa_update_option('usernameless_login', $post_usernameless_login); - $post_password_reset = sanitize_text_field($_POST['password_reset']); + $post_password_reset = sanitize_text_field(wp_unslash($_POST['password_reset'])); if($post_password_reset !== wwa_get_option('password_reset')){ wwa_add_log($res_id, 'password_reset: "'.wwa_get_option('password_reset').'"->"'.$post_password_reset.'"'); } wwa_update_option('password_reset', $post_password_reset); - $post_after_user_registration = sanitize_text_field($_POST['after_user_registration']); + $post_after_user_registration = sanitize_text_field(wp_unslash($_POST['after_user_registration'])); if($post_after_user_registration !== wwa_get_option('after_user_registration')){ wwa_add_log($res_id, 'after_user_registration: "'.wwa_get_option('after_user_registration').'"->"'.$post_after_user_registration.'"'); } @@ -138,7 +142,7 @@ if(wwa_validate_privileges()){ ?> - + @@ -316,6 +320,7 @@ if($wwa_v_log === false){


    - +

    your profile.', 'wp-webauthn'), admin_url('profile.php'));?>

    diff --git a/wp-content/plugins/wp-webauthn/wwa-ajax.php b/wp-content/plugins/wp-webauthn/wwa-ajax.php index 899a8f31..a9a658b2 100644 --- a/wp-content/plugins/wp-webauthn/wwa-ajax.php +++ b/wp-content/plugins/wp-webauthn/wwa-ajax.php @@ -67,14 +67,14 @@ class PublicKeyCredentialSourceRepository implements PublicKeyCredentialSourceRe public function updateCredentialLastUsed(string $publicKeyCredentialId): void { $credential = $this->findOneMetaByCredentialId($publicKeyCredentialId); if($credential !== null){ - $credential["last_used"] = date('Y-m-d H:i:s', current_time('timestamp')); + $credential["last_used"] = date('Y-m-d H:i:s', current_time('timestamp')); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date $meta = json_decode(wwa_get_option("user_credentials_meta"), true); $meta[base64_encode($publicKeyCredentialId)] = $credential; - wwa_update_option("user_credentials_meta", json_encode($meta)); + wwa_update_option("user_credentials_meta", wp_json_encode($meta)); } } - // List all authenticators + // List all authenticators for the front-end public function getShowList(PublicKeyCredentialUserEntity $publicKeyCredentialUserEntity): array { $data = json_decode(wwa_get_option("user_credentials_meta"), true); $arr = array(); @@ -91,7 +91,7 @@ class PublicKeyCredentialSourceRepository implements PublicKeyCredentialSourceRe )); } } - return array_map(function($item){return array("key" => $item["key"], "name" => $item["name"], "type" => $item["type"], "added" => $item["added"], "usernameless" => $item["usernameless"], "last_used" => $item["last_used"]);}, $arr); + return array_map(function($item){return array("key" => $item["key"], "name" => esc_html($item["name"]), "type" => $item["type"], "added" => $item["added"], "usernameless" => $item["usernameless"], "last_used" => $item["last_used"]);}, $arr); } // Modify an authenticator @@ -105,7 +105,7 @@ class PublicKeyCredentialSourceRepository implements PublicKeyCredentialSourceRe if(base64_encode($item->getPublicKeyCredentialId()) === base64_decode(str_pad(strtr($id, '-_', '+/'), strlen($id) % 4, '=', STR_PAD_RIGHT))){ if($action === "rename"){ $this->renameCredential(base64_encode($item->getPublicKeyCredentialId()), $name, $res_id); - }else if($action === "remove"){ + }elseif($action === "remove"){ $this->removeCredential(base64_encode($item->getPublicKeyCredentialId()), $res_id); } wwa_add_log($res_id, "ajax_modify_authenticator: Done"); @@ -122,7 +122,7 @@ class PublicKeyCredentialSourceRepository implements PublicKeyCredentialSourceRe $meta = json_decode(wwa_get_option("user_credentials_meta"), true); wwa_add_log($res_id, "ajax_modify_authenticator: Rename \"".base64_decode($meta[$id]["human_name"])."\" -> \"".$name."\""); $meta[$id]["human_name"] = base64_encode($name); - wwa_update_option("user_credentials_meta", json_encode($meta)); + wwa_update_option("user_credentials_meta", wp_json_encode($meta)); } // Remove a credential from database by credential ID @@ -133,7 +133,7 @@ class PublicKeyCredentialSourceRepository implements PublicKeyCredentialSourceRe $meta = json_decode(wwa_get_option("user_credentials_meta"), true); wwa_add_log($res_id, "ajax_modify_authenticator: Remove \"".base64_decode($meta[$id]["human_name"])."\""); unset($meta[$id]); - wwa_update_option("user_credentials_meta", json_encode($meta)); + wwa_update_option("user_credentials_meta", wp_json_encode($meta)); } // Read credential database @@ -150,14 +150,21 @@ class PublicKeyCredentialSourceRepository implements PublicKeyCredentialSourceRe // Save credentials data private function write(array $data, string $key, bool $usernameless = false): void { - if(isset($_POST["type"]) && ($_POST["type"] === "platform" || $_POST["type"] == "cross-platform" || $_POST["type"] === "none") && $key !== ''){ + if(isset($_POST["name"]) && isset($_POST["type"]) && ($_POST["type"] === "platform" || $_POST["type"] == "cross-platform" || $_POST["type"] === "none") && $key !== ''){ // Save credentials's meta separately $source = $data[$key]->getUserHandle(); $meta = json_decode(wwa_get_option("user_credentials_meta"), true); - $meta[$key] = array("human_name" => base64_encode(sanitize_text_field($_POST["name"])), "added" => date('Y-m-d H:i:s', current_time('timestamp')), "authenticator_type" => $_POST["type"], "user" => $source, "usernameless" => $usernameless, "last_used" => "-"); - wwa_update_option("user_credentials_meta", json_encode($meta)); + $meta[$key] = array( + "human_name" => base64_encode(sanitize_text_field(wp_unslash($_POST["name"]))), + "added" => date('Y-m-d H:i:s', current_time('timestamp')), // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date + "authenticator_type" => sanitize_text_field(wp_unslash($_POST["type"])), + "user" => $source, + "usernameless" => $usernameless, + "last_used" => "-" + ); + wwa_update_option("user_credentials_meta", wp_json_encode($meta)); } - wwa_update_option("user_credentials", json_encode($data)); + wwa_update_option("user_credentials", wp_json_encode($data)); } } @@ -188,16 +195,16 @@ function wwa_ajax_create(){ }else{ // Sanitize the input $wwa_get = array(); - $wwa_get["name"] = sanitize_text_field($_GET["name"]); - $wwa_get["type"] = sanitize_text_field($_GET["type"]); - $wwa_get["usernameless"] = sanitize_text_field($_GET["usernameless"]); + $wwa_get["name"] = sanitize_text_field(wp_unslash($_GET["name"])); + $wwa_get["type"] = sanitize_text_field(wp_unslash($_GET["type"])); + $wwa_get["usernameless"] = sanitize_text_field(wp_unslash($_GET["usernameless"])); wwa_add_log($res_id, "ajax_create: name => \"".$wwa_get["name"]."\", type => \"".$wwa_get["type"]."\", usernameless => \"".$wwa_get["usernameless"]."\""); } $user_info = wp_get_current_user(); if(isset($_GET["user_id"])){ - $user_id = intval(sanitize_text_field($_GET["user_id"])); + $user_id = intval(sanitize_text_field(wp_unslash($_GET["user_id"]))); if($user_id <= 0){ wwa_add_log($res_id, "ajax_create: (ERROR)Wrong parameters, exit"); wwa_wp_die("Bad Request."); @@ -287,12 +294,12 @@ function wwa_ajax_create(){ return $credential->getPublicKeyCredentialDescriptor(); }, $credentialSources); - wwa_add_log($res_id, "ajax_create: excludeCredentials => ".json_encode($excludeCredentials)); + wwa_add_log($res_id, "ajax_create: excludeCredentials => ".wp_json_encode($excludeCredentials)); // Set authenticator type if($wwa_get["type"] === "platform"){ $authenticator_type = AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_PLATFORM; - }else if($wwa_get["type"] === "cross-platform"){ + }elseif($wwa_get["type"] === "cross-platform"){ $authenticator_type = AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM; }else{ $authenticator_type = AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_NO_PREFERENCE; @@ -335,9 +342,9 @@ function wwa_ajax_create(){ wwa_set_temp_val("bind_config", array("name" => $wwa_get["name"], "type" => $wwa_get["type"], "usernameless" => $resident_key), $client_id); header("Content-Type: application/json"); - $publicKeyCredentialCreationOptions = json_decode(json_encode($publicKeyCredentialCreationOptions), true); + $publicKeyCredentialCreationOptions = json_decode(wp_json_encode($publicKeyCredentialCreationOptions), true); $publicKeyCredentialCreationOptions["clientID"] = $client_id; - echo json_encode($publicKeyCredentialCreationOptions); + echo wp_json_encode($publicKeyCredentialCreationOptions); wwa_add_log($res_id, "ajax_create: Challenge sent"); exit; }catch(\Exception $exception){ @@ -368,12 +375,13 @@ function wwa_ajax_create_response(){ wwa_add_log($res_id, "ajax_create_response: (ERROR)Missing parameters, exit"); wp_die("Bad Request."); }else{ - if(strlen($_POST["clientid"]) < 34 || strlen($_POST["clientid"]) > 35){ + // Sanitize the input + $post_client_id = sanitize_text_field(wp_unslash($_POST["clientid"])); + if(strlen($post_client_id) < 34 || strlen($post_client_id) > 35){ wwa_add_log($res_id, "ajax_create_response: (ERROR)Wrong client ID, exit"); wwa_wp_die("Bad Request.", $client_id); } - // Sanitize the input - $client_id = sanitize_text_field($_POST["clientid"]); + $client_id = $post_client_id; } if(!current_user_can("read")){ @@ -388,15 +396,15 @@ function wwa_ajax_create_response(){ }else{ // Sanitize the input $wwa_post = array(); - $wwa_post["name"] = sanitize_text_field($_POST["name"]); - $wwa_post["type"] = sanitize_text_field($_POST["type"]); - $wwa_post["usernameless"] = sanitize_text_field($_POST["usernameless"]); + $wwa_post["name"] = sanitize_text_field(wp_unslash($_POST["name"])); + $wwa_post["type"] = sanitize_text_field(wp_unslash($_POST["type"])); + $wwa_post["usernameless"] = sanitize_text_field(wp_unslash($_POST["usernameless"])); wwa_add_log($res_id, "ajax_create_response: name => \"".$wwa_post["name"]."\", type => \"".$wwa_post["type"]."\", usernameless => \"".$wwa_post["usernameless"]."\""); - wwa_add_log($res_id, "ajax_create_response: data => ".base64_decode($_POST["data"])); + wwa_add_log($res_id, "ajax_create_response: data => ".base64_decode(sanitize_text_field(wp_unslash($_POST["data"])))); } - if(isset($_GET["user_id"])){ - $user_id = intval(sanitize_text_field($_POST["user_id"])); + if(isset($_POST["user_id"])){ + $user_id = intval(sanitize_text_field(wp_unslash($_POST["user_id"]))); if($user_id <= 0){ wwa_add_log($res_id, "ajax_create_response: (ERROR)Wrong parameters, exit"); wwa_wp_die("Bad Request."); @@ -432,8 +440,13 @@ function wwa_ajax_create_response(){ wwa_wp_die("Bad Request.", $client_id); } + if(!isset($_POST["data"]) || $_POST["data"] === ""){ + wwa_add_log($res_id, "ajax_create_response: (ERROR)Empty data, exit"); + wwa_wp_die("Bad Request.", $client_id); + } + // Check global unique credential ID - $credential_id = base64_decode(json_decode(base64_decode($_POST["data"]), true)["rawId"]); + $credential_id = base64_decode(json_decode(base64_decode(sanitize_text_field(wp_unslash($_POST["data"]))), true)["rawId"]); $publicKeyCredentialSourceRepository = new PublicKeyCredentialSourceRepository(); if($publicKeyCredentialSourceRepository->findOneMetaByCredentialId($credential_id) !== null){ wwa_add_log($res_id, "ajax_create_response: (ERROR)Credential ID not unique, ID => \"".base64_encode($credential_id)."\" , exit"); @@ -473,7 +486,7 @@ function wwa_ajax_create_response(){ // Verify try { $publicKeyCredentialSource = $server->loadAndCheckAttestationResponse( - base64_decode($_POST["data"]), + base64_decode(sanitize_text_field(wp_unslash($_POST["data"]))), unserialize(base64_decode($temp_val["pkcco"])), $serverRequest ); @@ -532,12 +545,12 @@ function wwa_ajax_auth_start(){ }else{ // Sanitize the input $wwa_get = array(); - $wwa_get["type"] = sanitize_text_field($_GET["type"]); + $wwa_get["type"] = sanitize_text_field(wp_unslash($_GET["type"])); if(isset($_GET["user"])){ - $wwa_get["user"] = sanitize_text_field($_GET["user"]); + $wwa_get["user"] = sanitize_text_field(wp_unslash($_GET["user"])); } if(isset($_GET["usernameless"])){ - $wwa_get["usernameless"] = sanitize_text_field($_GET["usernameless"]); + $wwa_get["usernameless"] = sanitize_text_field(wp_unslash($_GET["usernameless"])); // Usernameless authentication not allowed if($wwa_get["usernameless"] === "true" && wwa_get_option("usernameless_login") !== "true"){ wwa_add_log($res_id, "ajax_auth: (ERROR)Usernameless authentication not allowed, exit"); @@ -563,7 +576,7 @@ function wwa_ajax_auth_start(){ $user_info = wp_get_current_user(); if(isset($_GET["user_id"])){ - $user_id = intval(sanitize_text_field($_GET["user_id"])); + $user_id = intval(sanitize_text_field(wp_unslash($_GET["user_id"]))); if($user_id <= 0){ wwa_add_log($res_id, "ajax_auth: (ERROR)Wrong parameters, exit"); wwa_wp_die("Bad Request."); @@ -617,7 +630,7 @@ function wwa_ajax_auth_start(){ $user_icon = get_avatar_url($user_info->user_email, array("scheme" => "https")); wwa_add_log($res_id, "ajax_auth: type => \"auth\", user => \"".$user_info->user_login."\""); if(!isset(wwa_get_option("user_id")[$user_info->user_login])){ - wwa_add_log($res_id, "ajax_auth: User not initialized, initialize"); + wwa_add_log($res_id, "ajax_auth: User found but not initialized, create a fake id"); $user_key = hash("sha256", $wwa_get["user"]."-".$wwa_get["user"]."-".wwa_generate_random_string(10)); $user_exist = false; }else{ @@ -654,8 +667,8 @@ function wwa_ajax_auth_start(){ $credentialSourceRepository = new PublicKeyCredentialSourceRepository(); $rpEntity = new PublicKeyCredentialRpEntity( - wwa_get_option('website_name'), - wwa_get_option('website_domain') + wwa_get_option("website_name"), + wwa_get_option("website_domain") ); $server = new Server( @@ -671,16 +684,16 @@ function wwa_ajax_auth_start(){ }else{ // Get the list of authenticators associated to the user // $credentialSources = $credentialSourceRepository->findAllForUserEntity($userEntity); - $allow_authenticator_type = wwa_get_option('allow_authenticator_type'); - if($allow_authenticator_type === false || $allow_authenticator_type === 'none'){ + $allow_authenticator_type = wwa_get_option("allow_authenticator_type"); + if($allow_authenticator_type === false || $allow_authenticator_type === "none"){ $credentialSources = $credentialSourceRepository->findAllForUserEntity($userEntity); - }else if($allow_authenticator_type !== false && $allow_authenticator_type !== 'none'){ + }elseif($allow_authenticator_type !== false && $allow_authenticator_type !== "none"){ wwa_add_log($res_id, "ajax_auth: allow_authenticator_type => \"".$allow_authenticator_type."\", filter authenticators"); $credentialSources = $credentialSourceRepository->findCredentialsForUserEntityByType($userEntity, $allow_authenticator_type); } // Logged in and testing, if the user haven't bind a authenticator yet, exit - if(count($credentialSources) === 0 && $wwa_get["type"] === "test" && current_user_can('read')){ + if(count($credentialSources) === 0 && $wwa_get["type"] === "test" && current_user_can("read")){ wwa_add_log($res_id, "ajax_auth: (ERROR)No authenticator, exit"); wwa_wp_die("User not inited.", $client_id); } @@ -690,7 +703,7 @@ function wwa_ajax_auth_start(){ return $credential->getPublicKeyCredentialDescriptor(); }, $credentialSources); - wwa_add_log($res_id, "ajax_auth: allowedCredentials => ".json_encode($allowedCredentials)); + wwa_add_log($res_id, "ajax_auth: allowedCredentials => ".wp_json_encode($allowedCredentials)); } // Set user verification @@ -728,9 +741,9 @@ function wwa_ajax_auth_start(){ } header("Content-Type: application/json"); - $publicKeyCredentialRequestOptions = json_decode(json_encode($publicKeyCredentialRequestOptions), true); + $publicKeyCredentialRequestOptions = json_decode(wp_json_encode($publicKeyCredentialRequestOptions), true); $publicKeyCredentialRequestOptions["clientID"] = $client_id; - echo json_encode($publicKeyCredentialRequestOptions); + echo wp_json_encode($publicKeyCredentialRequestOptions); wwa_add_log($res_id, "ajax_auth: Challenge sent"); exit; }catch(\Exception $exception){ @@ -761,12 +774,13 @@ function wwa_ajax_auth(){ wwa_add_log($res_id, "ajax_auth_response: (ERROR)Missing parameters, exit"); wp_die("Bad Request."); }else{ - if(strlen($_POST["clientid"]) < 34 || strlen($_POST["clientid"]) > 35){ + // Sanitize the input + $post_client_id = sanitize_text_field(wp_unslash($_POST["clientid"])); + if(strlen($post_client_id) < 34 || strlen($post_client_id) > 35){ wwa_add_log($res_id, "ajax_auth_response: (ERROR)Wrong client ID, exit"); wwa_wp_die("Bad Request.", $client_id); } - // Sanitize the input - $client_id = sanitize_text_field($_POST["clientid"]); + $client_id = $post_client_id; } // Check POST @@ -776,8 +790,8 @@ function wwa_ajax_auth(){ }else{ // Sanitize the input $wwa_post = array(); - $wwa_post["type"] = sanitize_text_field($_POST["type"]); - $wwa_post["remember"] = sanitize_text_field($_POST["remember"]); + $wwa_post["type"] = sanitize_text_field(wp_unslash($_POST["type"])); + $wwa_post["remember"] = sanitize_text_field(wp_unslash($_POST["remember"])); } $temp_val = array( @@ -798,7 +812,7 @@ function wwa_ajax_auth(){ if($wwa_post["remember"] !== "true" && $wwa_post["remember"] !== "false"){ wwa_add_log($res_id, "ajax_auth_response: (ERROR)Wrong parameters, exit"); wwa_wp_die("Bad Request.", $client_id); - }else if(wwa_get_option("remember_me") !== "true" && $wwa_post["remember"] === "true"){ + }elseif(wwa_get_option("remember_me") !== "true" && $wwa_post["remember"] === "true"){ wwa_add_log($res_id, "ajax_auth_response: (ERROR)Wrong parameters, exit"); wwa_wp_die("Bad Request.", $client_id); } @@ -843,8 +857,8 @@ function wwa_ajax_auth(){ if($wwa_post["type"] === "test" && current_user_can('read') && !$usernameless_flag){ $user_info = wp_get_current_user(); - if(isset($_GET["user_id"])){ - $user_id = intval(sanitize_text_field($_POST["user_id"])); + if(isset($_POST["user_id"])){ + $user_id = intval(sanitize_text_field(wp_unslash($_POST["user_id"]))); if($user_id <= 0){ wwa_add_log($res_id, "ajax_auth_response: (ERROR)Wrong parameters, exit"); wwa_wp_die("Bad Request."); @@ -882,7 +896,7 @@ function wwa_ajax_auth(){ wwa_add_log($res_id, "ajax_auth_response: type => \"test\", user => \"".$user_info->user_login."\""); }else{ if($usernameless_flag){ - $data_array = json_decode(base64_decode($_POST["data"]), true); + $data_array = json_decode(base64_decode(sanitize_text_field(wp_unslash($_POST["data"]))), true); if(!isset($data_array["response"]["userHandle"]) || !isset($data_array["rawId"])){ wwa_add_log($res_id, "ajax_auth_response: (ERROR)Client data not correct, exit"); wwa_wp_die("Bad request.", $client_id); @@ -964,7 +978,8 @@ function wwa_ajax_auth(){ } } - wwa_add_log($res_id, "ajax_auth_response: data => ".base64_decode($_POST["data"])); + $decoded_data = base64_decode(sanitize_text_field(wp_unslash($_POST["data"]))); + wwa_add_log($res_id, "ajax_auth_response: data => ".$decoded_data); if($temp_val["user_exist"]){ $rpEntity = new PublicKeyCredentialRpEntity( @@ -988,7 +1003,7 @@ function wwa_ajax_auth(){ // Verify try { $server->loadAndCheckAssertionResponse( - base64_decode($_POST["data"]), + $decoded_data, unserialize(base64_decode($temp_val["pkcco_auth"])), $userEntity, $serverRequest @@ -997,7 +1012,7 @@ function wwa_ajax_auth(){ wwa_add_log($res_id, "ajax_auth_response: Challenge verified"); // Success - $publicKeyCredentialSourceRepository->updateCredentialLastUsed(base64_decode(json_decode(base64_decode($_POST["data"]), true)["rawId"])); + $publicKeyCredentialSourceRepository->updateCredentialLastUsed(base64_decode(json_decode($decoded_data, true)["rawId"])); if(!($wwa_post["type"] === "test" && current_user_can("read"))){ // Log user in if (!is_user_logged_in()) { @@ -1011,7 +1026,7 @@ function wwa_ajax_auth(){ $user = get_user_by("login", $user_login); - if($user_info === false){ + if($user === false){ wwa_add_log($res_id, "ajax_auth_response: (ERROR)Wrong user ID, exit"); wwa_wp_die("Something went wrong."); } @@ -1081,7 +1096,7 @@ function wwa_ajax_authenticator_list(){ $user_info = wp_get_current_user(); if(isset($_GET["user_id"])){ - $user_id = intval(sanitize_text_field($_GET["user_id"])); + $user_id = intval(sanitize_text_field(wp_unslash($_GET["user_id"]))); if($user_id <= 0){ wwa_add_log($res_id, "ajax_authenticator_list: (ERROR)Wrong parameters, exit"); wwa_wp_die("Bad Request."); @@ -1120,7 +1135,7 @@ function wwa_ajax_authenticator_list(){ ); $publicKeyCredentialSourceRepository = new PublicKeyCredentialSourceRepository(); - echo json_encode($publicKeyCredentialSourceRepository->getShowList($userEntity)); + echo wp_json_encode($publicKeyCredentialSourceRepository->getShowList($userEntity)); exit; } add_action("wp_ajax_wwa_authenticator_list" , "wwa_ajax_authenticator_list"); @@ -1147,7 +1162,7 @@ function wwa_ajax_modify_authenticator(){ $user_info = wp_get_current_user(); if(isset($_GET["user_id"])){ - $user_id = intval(sanitize_text_field($_GET["user_id"])); + $user_id = intval(sanitize_text_field(wp_unslash($_GET["user_id"]))); if($user_id <= 0){ wwa_add_log($res_id, "ajax_modify_authenticator: (ERROR)Wrong parameters, exit"); wwa_wp_die("Bad Request."); @@ -1198,9 +1213,9 @@ function wwa_ajax_modify_authenticator(){ $publicKeyCredentialSourceRepository = new PublicKeyCredentialSourceRepository(); if($_GET["target"] === "rename"){ - echo $publicKeyCredentialSourceRepository->modifyAuthenticator($_GET["id"], sanitize_text_field($_GET["name"]), $userEntity, "rename", $res_id); - }else if($_GET["target"] === "remove"){ - echo $publicKeyCredentialSourceRepository->modifyAuthenticator($_GET["id"], "", $userEntity, "remove", $res_id); + echo $publicKeyCredentialSourceRepository->modifyAuthenticator(sanitize_text_field(wp_unslash($_GET["id"])), sanitize_text_field(wp_unslash($_GET["name"])), $userEntity, "rename", $res_id); + }elseif($_GET["target"] === "remove"){ + echo $publicKeyCredentialSourceRepository->modifyAuthenticator(sanitize_text_field(wp_unslash($_GET["id"])), "", $userEntity, "remove", $res_id); } exit; }catch(\Exception $exception){ @@ -1230,7 +1245,7 @@ function wwa_ajax_get_log(){ if($log === false){ echo "[]"; }else{ - echo json_encode($log); + echo wp_json_encode($log); } exit; @@ -1253,4 +1268,3 @@ function wwa_ajax_clear_log(){ exit; } add_action("wp_ajax_wwa_clear_log" , "wwa_ajax_clear_log"); -?> \ No newline at end of file diff --git a/wp-content/plugins/wp-webauthn/wwa-compatibility.php b/wp-content/plugins/wp-webauthn/wwa-compatibility.php index 8c946c0c..57a46d61 100644 --- a/wp-content/plugins/wp-webauthn/wwa-compatibility.php +++ b/wp-content/plugins/wp-webauthn/wwa-compatibility.php @@ -3,4 +3,3 @@ if(has_action('wp_login', array('Two_Factor_Core', 'wp_login')) !== false){ remove_action('wp_login', array('Two_Factor_Core', 'wp_login'), 10, 2); } -?> \ No newline at end of file diff --git a/wp-content/plugins/wp-webauthn/wwa-functions.php b/wp-content/plugins/wp-webauthn/wwa-functions.php index c97cec41..ff4aadfb 100644 --- a/wp-content/plugins/wp-webauthn/wwa-functions.php +++ b/wp-content/plugins/wp-webauthn/wwa-functions.php @@ -29,7 +29,7 @@ function wwa_wp_die($message = '', $client_id = false){ if($client_id !== false){ wwa_destroy_temp_val($client_id); } - wp_die($message); + wp_die(esc_html($message)); } // Init data for new options @@ -65,7 +65,7 @@ function wwa_generate_random_string($length = 10){ $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_'; $randomString = ''; for($i = 0; $i < $length; $i++){ - $randomString .= $characters[rand(0, strlen($characters) - 1)]; + $randomString .= $characters[wp_rand(0, strlen($characters) - 1)]; } return $randomString; } @@ -132,8 +132,8 @@ function wwa_delete_user($user_id){ } } wwa_update_option('user_id', $all_user_meta); - wwa_update_option('user_credentials_meta', json_encode($all_credentials_meta)); - wwa_update_option('user_credentials', json_encode($all_credentials)); + wwa_update_option('user_credentials_meta', wp_json_encode($all_credentials_meta)); + wwa_update_option('user_credentials', wp_json_encode($all_credentials)); wwa_add_log($res_id, "Deleted user => \"".$user_data->user_login."\""); } add_action('delete_user', 'wwa_delete_user'); @@ -141,7 +141,7 @@ add_action('delete_user', 'wwa_delete_user'); // Add CSS and JS in login page function wwa_login_js(){ $wwa_not_allowed = false; - if(!function_exists('mb_substr') || !function_exists('gmp_intval') || !wwa_check_ssl() && (parse_url(site_url(), PHP_URL_HOST) !== 'localhost' && parse_url(site_url(), PHP_URL_HOST) !== '127.0.0.1')){ + if(!function_exists('mb_substr') || !function_exists('gmp_intval') || !wwa_check_ssl() && (wp_parse_url(site_url(), PHP_URL_HOST) !== 'localhost' && wp_parse_url(site_url(), PHP_URL_HOST) !== '127.0.0.1')){ $wwa_not_allowed = true; } wp_enqueue_script('wwa_login', plugins_url('js/login.js', __FILE__), array(), get_option('wwa_version')['version'], true); @@ -178,7 +178,7 @@ add_action('login_enqueue_scripts', 'wwa_login_js', 999); // Disable password login function wwa_disable_password($user){ - if(!function_exists('mb_substr') || !function_exists('gmp_intval') || !wwa_check_ssl() && (parse_url(site_url(), PHP_URL_HOST) !== 'localhost' && parse_url(site_url(), PHP_URL_HOST) !== '127.0.0.1')){ + if(!function_exists('mb_substr') || !function_exists('gmp_intval') || !wwa_check_ssl() && (wp_parse_url(site_url(), PHP_URL_HOST) !== 'localhost' && wp_parse_url(site_url(), PHP_URL_HOST) !== '127.0.0.1')){ return $user; } if(wwa_get_option('first_choice') === 'webauthn'){ @@ -209,7 +209,7 @@ add_action('register_new_user', 'wwa_handle_user_register'); // Disable Password Reset URL & Redirect function wwa_disable_lost_password(){ - if((wwa_get_option('password_reset') === 'admin' || wwa_get_option('password_reset') === 'all') && isset( $_GET['action'] )){ + if((wwa_get_option('password_reset') === 'admin' || wwa_get_option('password_reset') === 'all') && isset($_GET['action'])){ if(in_array($_GET['action'], array('lostpassword', 'retrievepassword', 'resetpass', 'rp'))){ wp_redirect(wp_login_url(), 302); exit; @@ -272,6 +272,7 @@ function wwa_no_authenticator_warning(){ if($show_notice_flag){?>
    +

    Register', 'wp-webauthn'), $first_choice === 'webauthn' ? __('the site', 'wp-webauthn') : __('your account', 'wp-webauthn'), admin_url('profile.php'));?>

    +

    this account haven\'t register any WebAuthn authenticator yet. This user may unable to login.', 'wp-webauthn'), $first_choice === 'webauthn' ? __('the site', 'wp-webauthn') : __('this account', 'wp-webauthn'));?>

    diff --git a/wp-content/plugins/wp-webauthn/wwa-menus.php b/wp-content/plugins/wp-webauthn/wwa-menus.php index 83545651..a3a81737 100644 --- a/wp-content/plugins/wp-webauthn/wwa-menus.php +++ b/wp-content/plugins/wp-webauthn/wwa-menus.php @@ -15,7 +15,7 @@ add_action('show_user_profile', 'wwa_user_profile_fields'); // Save setting to profile page function wwa_save_user_profile_fields($user_id){ - if(empty($_POST['_wpnonce']) || !wp_verify_nonce($_POST['_wpnonce'], 'update-user_'.$user_id)){ + if(empty($_POST['_wpnonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_wpnonce'])), 'update-user_'.$user_id)){ return; } @@ -29,7 +29,7 @@ function wwa_save_user_profile_fields($user_id){ if(!isset($_POST['webauthn_only'])){ update_user_meta($user_id, 'webauthn_only', 'false'); - }else if(sanitize_text_field($_POST['webauthn_only']) === 'true'){ + }elseif(sanitize_text_field(wp_unslash($_POST['webauthn_only'])) === 'true'){ update_user_meta($user_id, 'webauthn_only', 'true'); }else{ update_user_meta($user_id, 'webauthn_only', 'false'); diff --git a/wp-content/plugins/wp-webauthn/wwa-profile-content.php b/wp-content/plugins/wp-webauthn/wwa-profile-content.php index 0e0e4349..71633491 100644 --- a/wp-content/plugins/wp-webauthn/wwa-profile-content.php +++ b/wp-content/plugins/wp-webauthn/wwa-profile-content.php @@ -52,6 +52,7 @@ if(isset($_GET['wwa_registered']) && $_GET['wwa_registered'] === 'true'){ foreach($data as $key => $value){ if($user_id === $value["user"]){ $count++; + break; } } } @@ -67,7 +68,7 @@ if(isset($_GET['wwa_registered']) && $_GET['wwa_registered'] === 'true'){ } } $wwa_not_allowed = false; -if(!function_exists("mb_substr") || !function_exists("gmp_intval") || !wwa_check_ssl() && (parse_url(site_url(), PHP_URL_HOST) !== 'localhost' && parse_url(site_url(), PHP_URL_HOST) !== '127.0.0.1')){ +if(!function_exists("mb_substr") || !function_exists("gmp_intval") || !wwa_check_ssl() && (wp_parse_url(site_url(), PHP_URL_HOST) !== 'localhost' && wp_parse_url(site_url(), PHP_URL_HOST) !== '127.0.0.1')){ $wwa_not_allowed = true; ?>
    @@ -124,6 +125,7 @@ if(!function_exists("mb_substr") || !function_exists("gmp_intval") || !wwa_check

    +

    %s.
    You can register multiple authenticators for an account.', 'wp-webauthn'), $user->user_login);?>

    diff --git a/wp-content/plugins/wp-webauthn/wwa-shortcodes.php b/wp-content/plugins/wp-webauthn/wwa-shortcodes.php index a02a46fe..dd5fd7f8 100644 --- a/wp-content/plugins/wp-webauthn/wwa-shortcodes.php +++ b/wp-content/plugins/wp-webauthn/wwa-shortcodes.php @@ -70,22 +70,27 @@ function wwa_login_form_shortcode($vals){ $html_form = ''; + $html_form .= ' + + '; return $html_form; } @@ -115,7 +120,21 @@ function wwa_register_form_shortcode($vals){ wp_enqueue_style('wwa_frondend_css', plugins_url('css/frontend.css', __FILE__), array(), get_option('wwa_version')['version']); $allowed_type = wwa_get_option('allow_authenticator_type') === false ? 'none' : wwa_get_option('allow_authenticator_type'); - return '

    '.__('If a type is selected, the browser will only prompt for authenticators of selected type.
    Regardless of the type, you can only log in with the very same authenticators you\'ve registered.', 'wp-webauthn').'

    '.__('An easily identifiable name for the authenticator. DOES NOT affect the authentication process in anyway.', 'wp-webauthn').'

    '.((wwa_get_option('usernameless_login') === "true") ? '

    '.__('If registered authenticator with this feature, you can login without enter your username.
    Some authenticators like U2F-only authenticators and some browsers DO NOT support this feature.
    A record will be stored in the authenticator permanently untill you reset it.', 'wp-webauthn').'

    ' : '').'

         

    '; + return ' +
    + + +

    '.__('If a type is selected, the browser will only prompt for authenticators of selected type.
    Regardless of the type, you can only log in with the very same authenticators you\'ve registered.', 'wp-webauthn').'

    + + +

    '.__('An easily identifiable name for the authenticator. DOES NOT affect the authentication process in anyway.', 'wp-webauthn').'

    '.( + (wwa_get_option('usernameless_login') === "true") ? '

    '.__('If registered authenticator with this feature, you can login without enter your username.
    Some authenticators like U2F-only authenticators and some browsers DO NOT support this feature.
    A record will be stored in the authenticator permanently untill you reset it.', 'wp-webauthn').'

    ' : '' + ).'

         

    +
    '; } add_shortcode('wwa_register_form', 'wwa_register_form_shortcode'); @@ -153,9 +172,9 @@ function wwa_list_shortcode($vals){ ), $vals) ); - $thead = '
    '; + $thead = '
    '.__('Identifier', 'wp-webauthn').''.__('Type', 'wp-webauthn').''._x('Registered', 'time', 'wp-webauthn').''.__('Last used', 'time', 'wp-webauthn').''.__('Usernameless', 'wp-webauthn').''.__('Action', 'wp-webauthn').'
    '; $tbody = ''; - $tfoot = '
    '.__('Identifier', 'wp-webauthn').''.__('Type', 'wp-webauthn').''._x('Registered', 'time', 'wp-webauthn').''.__('Last used', 'wp-webauthn').''.__('Usernameless', 'wp-webauthn').''.__('Action', 'wp-webauthn').'
    '.__('Loading...', 'wp-webauthn').'
    '.__('Identifier', 'wp-webauthn').''.__('Type', 'wp-webauthn').''._x('Registered', 'time', 'wp-webauthn').''.__('Last used', 'time', 'wp-webauthn').''.__('Usernameless', 'wp-webauthn').''.__('Action', 'wp-webauthn').'

    '; + $tfoot = ''.__('Identifier', 'wp-webauthn').''.__('Type', 'wp-webauthn').''._x('Registered', 'time', 'wp-webauthn').''.__('Last used', 'wp-webauthn').''.__('Usernameless', 'wp-webauthn').''.__('Action', 'wp-webauthn').'

    '; // If always display if(!current_user_can("read")){ @@ -178,4 +197,3 @@ function wwa_list_shortcode($vals){ return $thead.$tbody.$tfoot; } add_shortcode('wwa_list', 'wwa_list_shortcode'); -?> \ No newline at end of file diff --git a/wp-content/plugins/wp-webauthn/wwa-version.php b/wp-content/plugins/wp-webauthn/wwa-version.php index 00d03298..1c9f67c1 100644 --- a/wp-content/plugins/wp-webauthn/wwa-version.php +++ b/wp-content/plugins/wp-webauthn/wwa-version.php @@ -1,6 +1,5 @@ '1.3.1', - 'commit' => '79260d5' + 'version' => '1.3.4', + 'commit' => 'b7ef5ce' ); -?> \ No newline at end of file