SEOPress - Version 5.8.0.5

Version Description

  • FIX Downgrade Google Auth API to prevent errors with hosting using PHP parser
  • FIX "Sorry, you do not have permission to edit the _seopress_robots_primary_cat custom field." error
  • FIX Remove "Inspect URL with Google" tab from Universal SEO metabox if disabled
Download this release

Release Info

Developer rainbowgeek
Plugin Icon 128x128 SEOPress
Version 5.8.0.5
Comparing to
See all releases

Code changes from version 5.8.0.4 to 5.8.0.5

Files changed (56) hide show
  1. assets/js/build/primary-category-select.asset.php +1 -1
  2. assets/js/build/primary-category-select.js +1 -1
  3. assets/js/build/primary-category-select.js.map +1 -0
  4. assets/js/src/primary-category-select.js +15 -6
  5. inc/admin/metaboxes/admin-metaboxes.php +4 -1
  6. inc/functions/options-instant-indexing.php +2 -2
  7. languages/wp-seopress.pot +16 -10
  8. public/gutenberg/primary-category-select.asset.php +1 -0
  9. public/gutenberg/primary-category-select.js +1 -0
  10. readme.txt +7 -2
  11. seopress-functions.php +12 -8
  12. seopress.php +3 -3
  13. src/Actions/Admin/ModuleMetabox.php +2 -2
  14. src/Actions/Api/Metas/AdvancedSettings.php +29 -7
  15. src/Services/Options/ToggleOption.php +4 -0
  16. vendor/composer/installed.json +20 -25
  17. vendor/composer/installed.php +8 -8
  18. vendor/firebase/php-jwt/README.md +30 -98
  19. vendor/firebase/php-jwt/composer.json +2 -7
  20. vendor/firebase/php-jwt/src/CachedKeySet.php +0 -231
  21. vendor/firebase/php-jwt/src/JWK.php +22 -41
  22. vendor/firebase/php-jwt/src/JWT.php +162 -177
  23. vendor/firebase/php-jwt/src/Key.php +15 -20
  24. vendor/google/auth/.php-cs-fixer.dist.php +24 -0
  25. vendor/google/auth/CHANGELOG.md +211 -0
  26. vendor/google/auth/CODE_OF_CONDUCT.md +43 -0
  27. vendor/google/auth/composer.json +4 -4
  28. vendor/google/auth/renovate.json +6 -0
  29. vendor/google/auth/src/AccessToken.php +38 -45
  30. vendor/google/auth/src/ApplicationDefaultCredentials.php +13 -25
  31. vendor/google/auth/src/Cache/Item.php +26 -13
  32. vendor/google/auth/src/Cache/MemoryCacheItemPool.php +15 -14
  33. vendor/google/auth/src/Cache/SysVCacheItemPool.php +24 -32
  34. vendor/google/auth/src/Cache/TypedItem.php +0 -166
  35. vendor/google/auth/src/CacheTrait.php +5 -32
  36. vendor/google/auth/src/Credentials/AppIdentityCredentials.php +15 -23
  37. vendor/google/auth/src/Credentials/GCECredentials.php +12 -13
  38. vendor/google/auth/src/Credentials/IAMCredentials.php +6 -6
  39. vendor/google/auth/src/Credentials/InsecureCredentials.php +5 -3
  40. vendor/google/auth/src/Credentials/ServiceAccountCredentials.php +19 -30
  41. vendor/google/auth/src/Credentials/ServiceAccountJwtAccessCredentials.php +10 -15
  42. vendor/google/auth/src/Credentials/UserRefreshCredentials.php +12 -16
  43. vendor/google/auth/src/CredentialsLoader.php +47 -19
  44. vendor/google/auth/src/FetchAuthTokenCache.php +16 -17
  45. vendor/google/auth/src/FetchAuthTokenInterface.php +5 -5
  46. vendor/google/auth/src/GCECache.php +11 -1
  47. vendor/google/auth/src/HttpHandler/Guzzle5HttpHandler.php +0 -3
  48. vendor/google/auth/src/HttpHandler/Guzzle6HttpHandler.php +2 -2
  49. vendor/google/auth/src/HttpHandler/HttpHandlerFactory.php +0 -1
  50. vendor/google/auth/src/Iam.php +1 -1
  51. vendor/google/auth/src/Middleware/AuthTokenMiddleware.php +4 -11
  52. vendor/google/auth/src/Middleware/ProxyAuthTokenMiddleware.php +3 -10
  53. vendor/google/auth/src/Middleware/ScopedAccessTokenMiddleware.php +13 -3
  54. vendor/google/auth/src/Middleware/SimpleMiddleware.php +2 -2
  55. vendor/google/auth/src/OAuth2.php +75 -205
  56. vendor/google/auth/src/UpdateMetadataInterface.php +2 -2
assets/js/build/primary-category-select.asset.php CHANGED
@@ -1 +1 @@
1
- <?php return array('dependencies' => array('wp-components', 'wp-data', 'wp-element', 'wp-i18n'), 'version' => 'd4454d6cec16e500ca82');
1
+ <?php return array('dependencies' => array('wp-components', 'wp-data', 'wp-element', 'wp-i18n'), 'version' => 'bb30f36e5b37e25c33db');
assets/js/build/primary-category-select.js CHANGED
@@ -1 +1 @@
1
- !function(){"use strict";var e=window.wp.i18n,t=window.wp.element,r=window.wp.data,n=window.wp.components;function o(e){return o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o(e)}function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function s(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function c(e,t){return c=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},c(e,t)}function l(e,t){if(t&&("object"===o(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return u(e)}function u(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function p(e){return p=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},p(e)}var m=function(t){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,"prototype",{writable:!1}),t&&c(e,t)}(y,t);var r,o,m,f,d=(m=y,f=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=p(m);if(f){var r=p(this).constructor;e=Reflect.construct(t,arguments,r)}else e=t.apply(this,arguments);return l(this,e)});function y(){var e;return i(this,y),(e=d.apply(this,arguments)).onChange=e.onChange.bind(u(e)),e.updateMetabox=e.updateMetabox.bind(u(e)),e.state={primaryTermId:"none",selectableTerms:[]},e}return r=y,(o=[{key:"componentDidMount",value:function(){var e=this,t=this.props.primaryTermId||"none";this.setState({primaryTermId:t}),this.metaboxField=document.querySelector("#seopress_robots_primary_cat"),this.metaboxField&&this.metaboxField.addEventListener("change",(function(t){e.setState({primaryTermId:t.target.value})}))}},{key:"componentDidUpdate",value:function(e,t){var r=this;if(e.allTerms!==this.props.allTerms||e.selectedTermIds!==this.props.selectedTermIds){var n=this.props.allTerms&&this.props.allTerms.length?this.props.allTerms.filter((function(e){return r.props.selectedTermIds.includes(e.id)})):[],o=this.props.selectedTermIds.length&&this.props.selectedTermIds.includes(parseInt(this.state.primaryTermId))?this.state.primaryTermId:"none";this.setState({selectableTerms:n,primaryTermId:o})}t.primaryTermId===this.state.primaryTermId&&t.selectableTerms===this.state.selectableTerms||this.updateMetabox(this.state.primaryTermId)}},{key:"updateMetabox",value:function(e){if(this.metaboxField){var t=this.getOptions().map((function(t){var r=t.value==e?'selected="selected"':"";return'<option value="'.concat(t.value,'" ').concat(r,">").concat(t.label,"</option>")}));this.metaboxField.value=e,this.metaboxField.innerHTML=t.join("")}}},{key:"getOptions",value:function(){return[{value:"none",label:(0,e.__)("None (will disable this feature)","wp-seopress")}].concat(function(e){if(Array.isArray(e))return a(e)}(t=this.state.selectableTerms.map((function(e){return{value:e.id,label:e.name}})))||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(t)||function(e,t){if(e){if("string"==typeof e)return a(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?a(e,t):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}());var t}},{key:"onChange",value:function(e){this.setState({primaryTermId:e})}},{key:"render",value:function(){return!!this.state.selectableTerms.length&&React.createElement(n.SelectControl,{label:(0,e.__)("Select a primary category","wp-seopress"),value:this.state.primaryTermId,options:this.getOptions(),onChange:this.onChange})}}])&&s(r.prototype,o),Object.defineProperty(r,"prototype",{writable:!1}),y}(t.Component),f=(0,r.withSelect)((function(e,t){var r=t.slug,n=e("core").getTaxonomy(r),o=n?e("core/editor").getEditedPostAttribute(n.rest_base):[];return{taxonomy:n,allTerms:e("core").getEntityRecords("taxonomy",r,{per_page:-1})||[],primaryTermId:e("core/editor").getEditedPostAttribute("meta")._seopress_robots_primary_cat||"none",selectedTermIds:o}}))(m);wp.hooks.addFilter("editor.PostTaxonomyType","wpseopress",(function(e){return function(t){return React.createElement(React.Fragment,null,React.createElement(e,t),t.slug&&"category"===t.slug&&React.createElement(n.PanelRow,{className:"seopress-primary-term-picker"},React.createElement(f,t)))}}))}();
1
+ !function(){"use strict";var e=window.wp.i18n,t=window.wp.element,r=window.wp.data,n=window.wp.components;function o(e){return o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o(e)}function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function s(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function l(e,t){return l=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},l(e,t)}function c(e,t){if(t&&("object"===o(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return u(e)}function u(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function p(e){return p=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},p(e)}var m=function(t){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,"prototype",{writable:!1}),t&&l(e,t)}(y,t);var r,o,m,f,d=(m=y,f=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=p(m);if(f){var r=p(this).constructor;e=Reflect.construct(t,arguments,r)}else e=t.apply(this,arguments);return c(this,e)});function y(){var e;return i(this,y),(e=d.apply(this,arguments)).onChange=e.onChange.bind(u(e)),e.updateMetabox=e.updateMetabox.bind(u(e)),e.onMetaboxChange=e.onMetaboxChange.bind(u(e)),e.state={primaryTermId:"none",selectableTerms:[]},e}return r=y,(o=[{key:"componentDidMount",value:function(){var e=this.props.primaryTermId||"none";this.setState({primaryTermId:e}),this.metaboxField=document.querySelector("#seopress_robots_primary_cat"),this.metaboxField&&this.metaboxField.addEventListener("change",this.onMetaboxChange)}},{key:"componentWillUnmount",value:function(){this.metaboxField&&this.metaboxField.removeEventListener("change",this.onMetaboxChange)}},{key:"componentDidUpdate",value:function(e,t){var r=this;if(e.allTerms!==this.props.allTerms||e.selectedTermIds!==this.props.selectedTermIds){var n=this.props.allTerms&&this.props.allTerms.length?this.props.allTerms.filter((function(e){return r.props.selectedTermIds.includes(e.id)})):[],o=this.props.selectedTermIds.length&&this.props.selectedTermIds.includes(parseInt(this.state.primaryTermId))?this.state.primaryTermId:"none";this.setState({selectableTerms:n,primaryTermId:o})}t.primaryTermId===this.state.primaryTermId&&t.selectableTerms===this.state.selectableTerms||this.updateMetabox(this.state.primaryTermId)}},{key:"updateMetabox",value:function(e){if(this.metaboxField&&this.state.selectableTerms&&this.state.selectableTerms.length){var t=this.getOptions().map((function(t){var r=t.value==e?'selected="selected"':"";return'<option value="'.concat(t.value,'" ').concat(r,">").concat(t.label,"</option>")}));this.metaboxField.value=e,this.metaboxField.innerHTML=t.join("")}}},{key:"getOptions",value:function(){return[{value:"none",label:(0,e.__)("None (will disable this feature)","wp-seopress")}].concat(function(e){if(Array.isArray(e))return a(e)}(t=this.state.selectableTerms.map((function(e){return{value:e.id,label:e.name}})))||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(t)||function(e,t){if(e){if("string"==typeof e)return a(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?a(e,t):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}());var t}},{key:"onChange",value:function(e){this.setState({primaryTermId:e})}},{key:"onMetaboxChange",value:function(e){this.setState({primaryTermId:e.target.value})}},{key:"render",value:function(){return!!this.metaboxField&&!!this.state.selectableTerms.length&&React.createElement(n.SelectControl,{label:(0,e.__)("Select a primary category","wp-seopress"),value:this.state.primaryTermId,options:this.getOptions(),onChange:this.onChange})}}])&&s(r.prototype,o),Object.defineProperty(r,"prototype",{writable:!1}),y}(t.Component),f=(0,r.withSelect)((function(e,t){var r=t.slug,n=e("core").getTaxonomy(r),o=n?e("core/editor").getEditedPostAttribute(n.rest_base):[];return{taxonomy:n,allTerms:e("core").getEntityRecords("taxonomy",r,{per_page:-1,context:"view"})||[],primaryTermId:e("core/editor").getEditedPostAttribute("meta")._seopress_robots_primary_cat||"none",selectedTermIds:o}}))(m);wp.hooks.addFilter("editor.PostTaxonomyType","wpseopress",(function(e){return function(t){return React.createElement(React.Fragment,null,React.createElement(e,t),t.slug&&"category"===t.slug&&React.createElement(n.PanelRow,{className:"seopress-primary-term-picker"},React.createElement(f,t)))}}))}();
assets/js/build/primary-category-select.js.map ADDED
@@ -0,0 +1 @@
 
1
+ {"version":3,"file":"primary-category-select.js","mappings":";;;;;;;;;;AAAA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;UCAA;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;;UAEA;UACA;UACA;;;;;WCtBA;WACA;WACA;WACA,eAAe,4BAA4B;WAC3C,eAAe;WACf,iCAAiC,WAAW;WAC5C;WACA;;;;;WCPA;WACA;WACA;WACA;WACA,yCAAyC,wCAAwC;WACjF;WACA;WACA;;;;;WCPA,8CAA8C;;;;;WCA9C;WACA;WACA;WACA,uDAAuD,iBAAiB;WACxE;WACA,gDAAgD,aAAa;WAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACNA;AACA;AACA;AACA;;IAEMK;;;;;EACF,sBAAc;IAAA;;IAAA;;IACV,2BAASC,SAAT;IACA,MAAKC,QAAL,GAAgB,MAAKA,QAAL,CAAcC,IAAd,+BAAhB;IACA,MAAKC,aAAL,GAAqB,MAAKA,aAAL,CAAmBD,IAAnB,+BAArB;IACA,MAAKE,KAAL,GAAa;MACTC,aAAa,EAAE,MADN;MAETC,eAAe,EAAE;IAFR,CAAb;IAJU;EAQb;;;;WAED,6BAAoB;MAAA;;MAChB,IAAMD,aAAa,GAAG,KAAKE,KAAL,CAAWF,aAAX,IAA4B,MAAlD;MACA,KAAKG,QAAL,CAAc;QAAEH,aAAa,EAAbA;MAAF,CAAd;MACA,KAAKI,YAAL,GAAoBC,QAAQ,CAACC,aAAT,CAAuB,8BAAvB,CAApB;;MACA,IAAI,KAAKF,YAAT,EAAuB;QACnB,KAAKA,YAAL,CAAkBG,gBAAlB,CAAmC,QAAnC,EAA6C,UAAAC,CAAC,EAAI;UAC9C,MAAI,CAACL,QAAL,CAAc;YAAEH,aAAa,EAAEQ,CAAC,CAACC,MAAF,CAASC;UAA1B,CAAd;QACH,CAFD;MAGH;IACJ;;;WAED,4BAAmBC,SAAnB,EAA8BC,SAA9B,EAAyC;MAAA;;MACrC;MACA,IAAID,SAAS,CAACE,QAAV,KAAuB,KAAKX,KAAL,CAAWW,QAAlC,IAA8CF,SAAS,CAACG,eAAV,KAA8B,KAAKZ,KAAL,CAAWY,eAA3F,EAA4G;QACxG,IAAMb,eAAe,GAAG,KAAKC,KAAL,CAAWW,QAAX,IAAuB,KAAKX,KAAL,CAAWW,QAAX,CAAoBE,MAA3C,GAAoD,KAAKb,KAAL,CAAWW,QAAX,CAAoBG,MAApB,CAA2B,UAAAC,IAAI;UAAA,OAAI,MAAI,CAACf,KAAL,CAAWY,eAAX,CAA2BI,QAA3B,CAAoCD,IAAI,CAACE,EAAzC,CAAJ;QAAA,CAA/B,CAApD,GAAuI,EAA/J;QACA,IAAMnB,aAAa,GAAG,CAAC,KAAKE,KAAL,CAAWY,eAAX,CAA2BC,MAA5B,IAAsC,CAAC,KAAKb,KAAL,CAAWY,eAAX,CAA2BI,QAA3B,CAAoCE,QAAQ,CAAC,KAAKrB,KAAL,CAAWC,aAAZ,CAA5C,CAAvC,GAAiH,MAAjH,GAA0H,KAAKD,KAAL,CAAWC,aAA3J;QACA,KAAKG,QAAL,CAAc;UAAEF,eAAe,EAAfA,eAAF;UAAmBD,aAAa,EAAbA;QAAnB,CAAd;MACH;;MACD,IAAIY,SAAS,CAACZ,aAAV,KAA4B,KAAKD,KAAL,CAAWC,aAAvC,IAAwDY,SAAS,CAACX,eAAV,KAA8B,KAAKF,KAAL,CAAWE,eAArG,EAAsH;QAClH,KAAKH,aAAL,CAAmB,KAAKC,KAAL,CAAWC,aAA9B;MACH;IACJ;;;WAED,uBAAcqB,cAAd,EAA8B;MAC1B,IAAI,KAAKjB,YAAT,EAAuB;QACnB,IAAMkB,OAAO,GAAG,KAAKC,UAAL,GAAkBC,GAAlB,CAAsB,UAAAC,MAAM,EAAI;UAC5C,IAAMC,QAAQ,GAAGD,MAAM,CAACf,KAAP,IAAgBW,cAAhB,GAAiC,qBAAjC,GAAyD,EAA1E;UACA,iCAAyBI,MAAM,CAACf,KAAhC,gBAA0CgB,QAA1C,cAAsDD,MAAM,CAACE,KAA7D;QACH,CAHe,CAAhB;QAIA,KAAKvB,YAAL,CAAkBM,KAAlB,GAA0BW,cAA1B;QACA,KAAKjB,YAAL,CAAkBwB,SAAlB,GAA8BN,OAAO,CAACO,IAAR,CAAa,EAAb,CAA9B;MACH;IACJ;;;WAED,sBAAa;MACT,QACI;QAAEnB,KAAK,EAAE,MAAT;QAAiBiB,KAAK,EAAEtC,mDAAE,CAAC,kCAAD,EAAqC,aAArC;MAA1B,CADJ,4BAEO,KAAKU,KAAL,CAAWE,eAAX,CAA2BuB,GAA3B,CAA+B,UAACP,IAAD;QAAA,OAAW;UAAEP,KAAK,EAAEO,IAAI,CAACE,EAAd;UAAkBQ,KAAK,EAAEV,IAAI,CAACa;QAA9B,CAAX;MAAA,CAA/B,CAFP;IAIH;;;WAED,kBAASC,MAAT,EAAiB;MACb,KAAK5B,QAAL,CAAc;QAAEH,aAAa,EAAE+B;MAAjB,CAAd;IACH;;;WAED,kBAAS;MACL,OAAO,CAAC,CAAC,KAAKhC,KAAL,CAAWE,eAAX,CAA2Bc,MAA7B,iBACH,oBAAC,gEAAD;QACI,KAAK,EAAE1B,mDAAE,CAAC,2BAAD,EAA8B,aAA9B,CADb;QAEI,KAAK,EAAE,KAAKU,KAAL,CAAWC,aAFtB;QAGI,OAAO,EAAE,KAAKuB,UAAL,EAHb;QAII,QAAQ,EAAE,KAAK3B;MAJnB,EADJ;IAQH;;;;EAjEoBN;;AAqEzB,IAAM0C,iBAAiB,GAAGzC,2DAAU,CAAC,UAAC0C,MAAD,QAAsB;EAAA,IAAXC,IAAW,QAAXA,IAAW;EACvD,IAAMC,QAAQ,GAAGF,MAAM,CAAC,MAAD,CAAN,CAAeG,WAAf,CAA2BF,IAA3B,CAAjB;EACA,IAAMpB,eAAe,GAAGqB,QAAQ,GAAGF,MAAM,CAAC,aAAD,CAAN,CAAsBI,sBAAtB,CAA6CF,QAAQ,CAACG,SAAtD,CAAH,GAAsE,EAAtG;EACA,IAAMzB,QAAQ,GAAGoB,MAAM,CAAC,MAAD,CAAN,CAAeM,gBAAf,CAAgC,UAAhC,EAA4CL,IAA5C,EAAkD;IAAEM,QAAQ,EAAE,CAAC;EAAb,CAAlD,KAAuE,EAAxF;EACA,IAAMxC,aAAa,GAAGiC,MAAM,CAAC,aAAD,CAAN,CAAsBI,sBAAtB,CAA6C,MAA7C,EAAqD,8BAArD,KAAwF,MAA9G;EACA,OAAO;IAAEF,QAAQ,EAARA,QAAF;IAAYtB,QAAQ,EAARA,QAAZ;IAAsBb,aAAa,EAAbA,aAAtB;IAAqCc,eAAe,EAAfA;EAArC,CAAP;AACH,CANmC,CAAV,CAMvBpB,UANuB,CAA1B;AASA+C,EAAE,CAACC,KAAH,CAASC,SAAT,CACI,yBADJ,EAEI,YAFJ,EAGI,UAACC,cAAD;EAAA,OAAoB,UAAC1C,KAAD,EAAW;IAC3B,oBACI,uDACI,oBAAC,cAAD,EAAoBA,KAApB,CADJ,EAEKA,KAAK,CAACgC,IAAN,IAAc,eAAehC,KAAK,CAACgC,IAAnC,iBACG,oBAAC,2DAAD;MAAU,SAAS,EAAC;IAApB,gBACI,oBAAC,iBAAD,EAAuBhC,KAAvB,CADJ,CAHR,CADJ;EAUH,CAXD;AAAA,CAHJ,E","sources":["webpack://wp-seopress/external window [\"wp\",\"components\"]","webpack://wp-seopress/external window [\"wp\",\"data\"]","webpack://wp-seopress/external window [\"wp\",\"element\"]","webpack://wp-seopress/external window [\"wp\",\"i18n\"]","webpack://wp-seopress/webpack/bootstrap","webpack://wp-seopress/webpack/runtime/compat get default export","webpack://wp-seopress/webpack/runtime/define property getters","webpack://wp-seopress/webpack/runtime/hasOwnProperty shorthand","webpack://wp-seopress/webpack/runtime/make namespace object","webpack://wp-seopress/./assets/js/src/primary-category-select.js"],"sourcesContent":["module.exports = window[\"wp\"][\"components\"];","module.exports = window[\"wp\"][\"data\"];","module.exports = window[\"wp\"][\"element\"];","module.exports = window[\"wp\"][\"i18n\"];","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { __ } from '@wordpress/i18n'\nimport { Component } from '@wordpress/element'\nimport { withSelect } from '@wordpress/data';\nimport { PanelRow, SelectControl } from '@wordpress/components'\n\nclass TermSelect extends Component {\n constructor() {\n super(...arguments);\n this.onChange = this.onChange.bind(this);\n this.updateMetabox = this.updateMetabox.bind(this);\n this.state = {\n primaryTermId: 'none',\n selectableTerms: [],\n }\n }\n\n componentDidMount() {\n const primaryTermId = this.props.primaryTermId || 'none';\n this.setState({ primaryTermId });\n this.metaboxField = document.querySelector('#seopress_robots_primary_cat');\n if (this.metaboxField) {\n this.metaboxField.addEventListener('change', e => {\n this.setState({ primaryTermId: e.target.value });\n });\n }\n }\n\n componentDidUpdate(prevProps, prevState) {\n // If available terms or selected terms have changed, check state.\n if (prevProps.allTerms !== this.props.allTerms || prevProps.selectedTermIds !== this.props.selectedTermIds) {\n const selectableTerms = this.props.allTerms && this.props.allTerms.length ? this.props.allTerms.filter(term => this.props.selectedTermIds.includes(term.id)) : [];\n const primaryTermId = !this.props.selectedTermIds.length || !this.props.selectedTermIds.includes(parseInt(this.state.primaryTermId)) ? 'none' : this.state.primaryTermId;\n this.setState({ selectableTerms, primaryTermId });\n }\n if (prevState.primaryTermId !== this.state.primaryTermId || prevState.selectableTerms !== this.state.selectableTerms) {\n this.updateMetabox(this.state.primaryTermId);\n }\n }\n\n updateMetabox(selectedTermId) {\n if (this.metaboxField) {\n const options = this.getOptions().map(option => {\n const selected = option.value == selectedTermId ? 'selected=\"selected\"' : '';\n return `<option value=\"${option.value}\" ${selected}>${option.label}</option>`;\n });\n this.metaboxField.value = selectedTermId;\n this.metaboxField.innerHTML = options.join('');\n }\n }\n\n getOptions() {\n return [\n { value: 'none', label: __('None (will disable this feature)', 'wp-seopress') },\n ...this.state.selectableTerms.map((term) => ({ value: term.id, label: term.name, }))\n ];\n }\n\n onChange(termId) {\n this.setState({ primaryTermId: termId });\n }\n\n render() {\n return !!this.state.selectableTerms.length && (\n <SelectControl\n label={__('Select a primary category', 'wp-seopress')}\n value={this.state.primaryTermId}\n options={this.getOptions()}\n onChange={this.onChange}\n />\n );\n }\n}\n\n\nconst PrimaryTermSelect = withSelect((select, { slug }) => {\n const taxonomy = select('core').getTaxonomy(slug);\n const selectedTermIds = taxonomy ? select('core/editor').getEditedPostAttribute(taxonomy.rest_base) : [];\n const allTerms = select('core').getEntityRecords('taxonomy', slug, { per_page: -1 }) || [];\n const primaryTermId = select('core/editor').getEditedPostAttribute('meta')['_seopress_robots_primary_cat'] || 'none';\n return { taxonomy, allTerms, primaryTermId, selectedTermIds }\n})(TermSelect);\n\n\nwp.hooks.addFilter(\n 'editor.PostTaxonomyType',\n 'wpseopress',\n (PostTaxonomies) => (props) => {\n return (\n <>\n <PostTaxonomies {...props} />\n {props.slug && 'category' === props.slug &&\n <PanelRow className=\"seopress-primary-term-picker\">\n <PrimaryTermSelect {...props} />\n </PanelRow>\n }\n </>\n );\n }\n)"],"names":["__","Component","withSelect","PanelRow","SelectControl","TermSelect","arguments","onChange","bind","updateMetabox","state","primaryTermId","selectableTerms","props","setState","metaboxField","document","querySelector","addEventListener","e","target","value","prevProps","prevState","allTerms","selectedTermIds","length","filter","term","includes","id","parseInt","selectedTermId","options","getOptions","map","option","selected","label","innerHTML","join","name","termId","PrimaryTermSelect","select","slug","taxonomy","getTaxonomy","getEditedPostAttribute","rest_base","getEntityRecords","per_page","wp","hooks","addFilter","PostTaxonomies"],"sourceRoot":""}
assets/js/src/primary-category-select.js CHANGED
@@ -8,6 +8,7 @@ class TermSelect extends Component {
8
  super(...arguments);
9
  this.onChange = this.onChange.bind(this);
10
  this.updateMetabox = this.updateMetabox.bind(this);
 
11
  this.state = {
12
  primaryTermId: 'none',
13
  selectableTerms: [],
@@ -19,9 +20,13 @@ class TermSelect extends Component {
19
  this.setState({ primaryTermId });
20
  this.metaboxField = document.querySelector('#seopress_robots_primary_cat');
21
  if (this.metaboxField) {
22
- this.metaboxField.addEventListener('change', e => {
23
- this.setState({ primaryTermId: e.target.value });
24
- });
 
 
 
 
25
  }
26
  }
27
 
@@ -38,7 +43,7 @@ class TermSelect extends Component {
38
  }
39
 
40
  updateMetabox(selectedTermId) {
41
- if (this.metaboxField) {
42
  const options = this.getOptions().map(option => {
43
  const selected = option.value == selectedTermId ? 'selected="selected"' : '';
44
  return `<option value="${option.value}" ${selected}>${option.label}</option>`;
@@ -59,8 +64,12 @@ class TermSelect extends Component {
59
  this.setState({ primaryTermId: termId });
60
  }
61
 
 
 
 
 
62
  render() {
63
- return !!this.state.selectableTerms.length && (
64
  <SelectControl
65
  label={__('Select a primary category', 'wp-seopress')}
66
  value={this.state.primaryTermId}
@@ -75,7 +84,7 @@ class TermSelect extends Component {
75
  const PrimaryTermSelect = withSelect((select, { slug }) => {
76
  const taxonomy = select('core').getTaxonomy(slug);
77
  const selectedTermIds = taxonomy ? select('core/editor').getEditedPostAttribute(taxonomy.rest_base) : [];
78
- const allTerms = select('core').getEntityRecords('taxonomy', slug, { per_page: -1 }) || [];
79
  const primaryTermId = select('core/editor').getEditedPostAttribute('meta')['_seopress_robots_primary_cat'] || 'none';
80
  return { taxonomy, allTerms, primaryTermId, selectedTermIds }
81
  })(TermSelect);
8
  super(...arguments);
9
  this.onChange = this.onChange.bind(this);
10
  this.updateMetabox = this.updateMetabox.bind(this);
11
+ this.onMetaboxChange = this.onMetaboxChange.bind(this);
12
  this.state = {
13
  primaryTermId: 'none',
14
  selectableTerms: [],
20
  this.setState({ primaryTermId });
21
  this.metaboxField = document.querySelector('#seopress_robots_primary_cat');
22
  if (this.metaboxField) {
23
+ this.metaboxField.addEventListener('change', this.onMetaboxChange);
24
+ }
25
+ }
26
+
27
+ componentWillUnmount() {
28
+ if (this.metaboxField) {
29
+ this.metaboxField.removeEventListener('change', this.onMetaboxChange);
30
  }
31
  }
32
 
43
  }
44
 
45
  updateMetabox(selectedTermId) {
46
+ if (this.metaboxField && this.state.selectableTerms && this.state.selectableTerms.length) {
47
  const options = this.getOptions().map(option => {
48
  const selected = option.value == selectedTermId ? 'selected="selected"' : '';
49
  return `<option value="${option.value}" ${selected}>${option.label}</option>`;
64
  this.setState({ primaryTermId: termId });
65
  }
66
 
67
+ onMetaboxChange(e) {
68
+ this.setState({ primaryTermId: e.target.value });
69
+ }
70
+
71
  render() {
72
+ return !!this.metaboxField && !!this.state.selectableTerms.length && (
73
  <SelectControl
74
  label={__('Select a primary category', 'wp-seopress')}
75
  value={this.state.primaryTermId}
84
  const PrimaryTermSelect = withSelect((select, { slug }) => {
85
  const taxonomy = select('core').getTaxonomy(slug);
86
  const selectedTermIds = taxonomy ? select('core/editor').getEditedPostAttribute(taxonomy.rest_base) : [];
87
+ const allTerms = select('core').getEntityRecords('taxonomy', slug, { per_page: -1, context: 'view' }) || [];
88
  const primaryTermId = select('core/editor').getEditedPostAttribute('meta')['_seopress_robots_primary_cat'] || 'none';
89
  return { taxonomy, allTerms, primaryTermId, selectedTermIds }
90
  })(TermSelect);
inc/admin/metaboxes/admin-metaboxes.php CHANGED
@@ -242,6 +242,7 @@ function seopress_display_seo_metaboxe()
242
  function seopress_cpt($post)
243
  {
244
  global $typenow;
 
245
  $prefix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
246
  wp_nonce_field(plugin_basename(__FILE__), 'seopress_cpt_nonce');
247
 
@@ -267,7 +268,9 @@ function seopress_display_seo_metaboxe()
267
  if (isset($get_current_screen->is_block_editor)) {
268
  if ($get_current_screen->is_block_editor) {
269
  wp_enqueue_script('seopress-block-editor-js', SEOPRESS_ASSETS_DIR . '/js/seopress-block-editor' . $prefix . '.js', ['jquery'], SEOPRESS_VERSION, true);
270
- wp_enqueue_script( 'seopress-primary-category-js', SEOPRESS_ASSETS_DIR . '/js/build/primary-category-select.js', ['wp-hooks'], SEOPRESS_VERSION, true);
 
 
271
  }
272
  }
273
  }
242
  function seopress_cpt($post)
243
  {
244
  global $typenow;
245
+ global $wp_version;
246
  $prefix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
247
  wp_nonce_field(plugin_basename(__FILE__), 'seopress_cpt_nonce');
248
 
268
  if (isset($get_current_screen->is_block_editor)) {
269
  if ($get_current_screen->is_block_editor) {
270
  wp_enqueue_script('seopress-block-editor-js', SEOPRESS_ASSETS_DIR . '/js/seopress-block-editor' . $prefix . '.js', ['jquery'], SEOPRESS_VERSION, true);
271
+ if ( version_compare( $wp_version, '5.8', '>=' ) ) {
272
+ wp_enqueue_script( 'seopress-primary-category-js', SEOPRESS_ASSETS_DIR . '/js/build/primary-category-select.js', ['wp-hooks'], SEOPRESS_VERSION, true);
273
+ }
274
  }
275
  }
276
  }
inc/functions/options-instant-indexing.php CHANGED
@@ -134,13 +134,13 @@ function seopress_instant_indexing_fn($is_manual_submission = true, $permalink =
134
  //Prepare the URLS
135
  if ($is_manual_submission === true) {
136
  $urls = preg_split('/\r\n|\r|\n/', $urls);
137
- $x_source_info = 'https://www.seopress.org/5.8.0.4/true';
138
 
139
  $urls = array_slice($urls, 0, 100);
140
  } elseif ($is_manual_submission === false && !empty($permalink)) {
141
  $urls = null;
142
  $urls[] = $permalink;
143
- $x_source_info = 'https://www.seopress.org/5.8.0.4/false';
144
  }
145
 
146
  //Bing API
134
  //Prepare the URLS
135
  if ($is_manual_submission === true) {
136
  $urls = preg_split('/\r\n|\r|\n/', $urls);
137
+ $x_source_info = 'https://www.seopress.org/5.8.0.5/true';
138
 
139
  $urls = array_slice($urls, 0, 100);
140
  } elseif ($is_manual_submission === false && !empty($permalink)) {
141
  $urls = null;
142
  $urls[] = $permalink;
143
+ $x_source_info = 'https://www.seopress.org/5.8.0.5/false';
144
  }
145
 
146
  //Bing API
languages/wp-seopress.pot CHANGED
@@ -2,14 +2,14 @@
2
  # This file is distributed under the GPLv2.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: SEOPress 5.8.0.4\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wp-seopress\n"
7
  "Last-Translator: SEOPress Team <contact@seopress.org>\n"
8
  "Language-Team: SEOPress Team <contact@seopress.org>\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
- "POT-Creation-Date: 2022-07-06T12:44:39+00:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
  "X-Generator: WP-CLI 2.6.0\n"
15
  "X-Domain: wp-seopress\n"
@@ -620,7 +620,7 @@ msgstr ""
620
  #: inc/admin/admin-pages/Sitemaps.php:43
621
  #: inc/admin/admin-pages/Social.php:43
622
  #: inc/admin/admin-pages/Titles.php:54
623
- #: seopress-functions.php:714
624
  msgid "Save changes"
625
  msgstr ""
626
 
@@ -1032,7 +1032,7 @@ msgid "Get started"
1032
  msgstr ""
1033
 
1034
  #: inc/admin/blocks/get-started.php:25
1035
- #: seopress-functions.php:505
1036
  msgid "Dismiss"
1037
  msgstr ""
1038
 
@@ -2702,8 +2702,11 @@ msgstr ""
2702
  #: inc/admin/page-builders/elementor/inc/admin/class-document-settings-section.php:286
2703
  #: inc/admin/wizard/admin-wizard.php:714
2704
  #: src/Helpers/Metas/RobotSettings.php:19
 
2705
  #: assets/js/build/primary-category-select.js:1
2706
- #: assets/js/src/primary-category-select.js:53
 
 
2707
  msgid "None (will disable this feature)"
2708
  msgstr ""
2709
 
@@ -3696,8 +3699,11 @@ msgstr ""
3696
  #: inc/admin/metaboxes/admin-metaboxes-form.php:334
3697
  #: inc/admin/page-builders/elementor/inc/admin/class-document-settings-section.php:293
3698
  #: src/Helpers/Metas/RobotSettings.php:109
 
3699
  #: assets/js/build/primary-category-select.js:1
3700
- #: assets/js/src/primary-category-select.js:65
 
 
3701
  msgid "Select a primary category"
3702
  msgstr ""
3703
 
@@ -4137,15 +4143,15 @@ msgstr ""
4137
  msgid "Add video"
4138
  msgstr ""
4139
 
4140
- #: inc/admin/metaboxes/admin-metaboxes.php:280
4141
- #: inc/admin/metaboxes/admin-metaboxes.php:656
4142
  #: inc/admin/metaboxes/admin-term-metaboxes.php:215
4143
  #: inc/admin/page-builders/elementor/inc/admin/class-document-settings-section.php:72
4144
  #: inc/admin/page-builders/elementor/inc/controls/class-content-analysis-control.php:35
4145
  msgid "Analysis in progress..."
4146
  msgstr ""
4147
 
4148
- #: inc/admin/metaboxes/admin-metaboxes.php:637
4149
  #: src/Services/ContentAnalysis/RenderContentAnalysis.php:19
4150
  msgid "Content analysis"
4151
  msgstr ""
@@ -5624,7 +5630,7 @@ msgid "Custom Taxonomies"
5624
  msgstr ""
5625
 
5626
  #. translators: %s: "Custom Post Types" or "Custom Taxonomies" %s: "title" or "description"
5627
- #: seopress-functions.php:332
5628
  msgid "Some <strong>%s</strong> have no <strong>meta %s</strong> set! We strongly encourage you to add one by filling in the fields below."
5629
  msgstr ""
5630
 
2
  # This file is distributed under the GPLv2.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: SEOPress 5.8.0.5\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wp-seopress\n"
7
  "Last-Translator: SEOPress Team <contact@seopress.org>\n"
8
  "Language-Team: SEOPress Team <contact@seopress.org>\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "POT-Creation-Date: 2022-07-08T13:09:11+00:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
  "X-Generator: WP-CLI 2.6.0\n"
15
  "X-Domain: wp-seopress\n"
620
  #: inc/admin/admin-pages/Sitemaps.php:43
621
  #: inc/admin/admin-pages/Social.php:43
622
  #: inc/admin/admin-pages/Titles.php:54
623
+ #: seopress-functions.php:718
624
  msgid "Save changes"
625
  msgstr ""
626
 
1032
  msgstr ""
1033
 
1034
  #: inc/admin/blocks/get-started.php:25
1035
+ #: seopress-functions.php:509
1036
  msgid "Dismiss"
1037
  msgstr ""
1038
 
2702
  #: inc/admin/page-builders/elementor/inc/admin/class-document-settings-section.php:286
2703
  #: inc/admin/wizard/admin-wizard.php:714
2704
  #: src/Helpers/Metas/RobotSettings.php:19
2705
+ #: app/gutenberg/primary-category-select/primary-category-select.js:75
2706
  #: assets/js/build/primary-category-select.js:1
2707
+ #: assets/js/src/primary-category-select.js:58
2708
+ #: public/gutenberg/primary-category-select.js:1
2709
+ #: assets/js/build/primary-category-select.js:106
2710
  msgid "None (will disable this feature)"
2711
  msgstr ""
2712
 
3699
  #: inc/admin/metaboxes/admin-metaboxes-form.php:334
3700
  #: inc/admin/page-builders/elementor/inc/admin/class-document-settings-section.php:293
3701
  #: src/Helpers/Metas/RobotSettings.php:109
3702
+ #: app/gutenberg/primary-category-select/primary-category-select.js:92
3703
  #: assets/js/build/primary-category-select.js:1
3704
+ #: assets/js/src/primary-category-select.js:74
3705
+ #: public/gutenberg/primary-category-select.js:1
3706
+ #: assets/js/build/primary-category-select.js:118
3707
  msgid "Select a primary category"
3708
  msgstr ""
3709
 
4143
  msgid "Add video"
4144
  msgstr ""
4145
 
4146
+ #: inc/admin/metaboxes/admin-metaboxes.php:283
4147
+ #: inc/admin/metaboxes/admin-metaboxes.php:659
4148
  #: inc/admin/metaboxes/admin-term-metaboxes.php:215
4149
  #: inc/admin/page-builders/elementor/inc/admin/class-document-settings-section.php:72
4150
  #: inc/admin/page-builders/elementor/inc/controls/class-content-analysis-control.php:35
4151
  msgid "Analysis in progress..."
4152
  msgstr ""
4153
 
4154
+ #: inc/admin/metaboxes/admin-metaboxes.php:640
4155
  #: src/Services/ContentAnalysis/RenderContentAnalysis.php:19
4156
  msgid "Content analysis"
4157
  msgstr ""
5630
  msgstr ""
5631
 
5632
  #. translators: %s: "Custom Post Types" or "Custom Taxonomies" %s: "title" or "description"
5633
+ #: seopress-functions.php:336
5634
  msgid "Some <strong>%s</strong> have no <strong>meta %s</strong> set! We strongly encourage you to add one by filling in the fields below."
5635
  msgstr ""
5636
 
public/gutenberg/primary-category-select.asset.php ADDED
@@ -0,0 +1 @@
 
1
+ <?php return array('dependencies' => array('wp-components', 'wp-data', 'wp-element', 'wp-i18n'), 'version' => 'd4454d6cec16e500ca82');
public/gutenberg/primary-category-select.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(){"use strict";var e=window.wp.i18n,t=window.wp.element,r=window.wp.data,n=window.wp.components;function o(e){return o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o(e)}function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function s(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function c(e,t){return c=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},c(e,t)}function l(e,t){if(t&&("object"===o(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return u(e)}function u(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function p(e){return p=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},p(e)}var m=function(t){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,"prototype",{writable:!1}),t&&c(e,t)}(y,t);var r,o,m,f,d=(m=y,f=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=p(m);if(f){var r=p(this).constructor;e=Reflect.construct(t,arguments,r)}else e=t.apply(this,arguments);return l(this,e)});function y(){var e;return i(this,y),(e=d.apply(this,arguments)).onChange=e.onChange.bind(u(e)),e.updateMetabox=e.updateMetabox.bind(u(e)),e.state={primaryTermId:"none",selectableTerms:[]},e}return r=y,(o=[{key:"componentDidMount",value:function(){var e=this,t=this.props.primaryTermId||"none";this.setState({primaryTermId:t}),this.metaboxField=document.querySelector("#seopress_robots_primary_cat"),this.metaboxField&&this.metaboxField.addEventListener("change",(function(t){e.setState({primaryTermId:t.target.value})}))}},{key:"componentDidUpdate",value:function(e,t){var r=this;if(e.allTerms!==this.props.allTerms||e.selectedTermIds!==this.props.selectedTermIds){var n=this.props.allTerms&&this.props.allTerms.length?this.props.allTerms.filter((function(e){return r.props.selectedTermIds.includes(e.id)})):[],o=this.props.selectedTermIds.length&&this.props.selectedTermIds.includes(parseInt(this.state.primaryTermId))?this.state.primaryTermId:"none";this.setState({selectableTerms:n,primaryTermId:o})}t.primaryTermId===this.state.primaryTermId&&t.selectableTerms===this.state.selectableTerms||this.updateMetabox(this.state.primaryTermId)}},{key:"updateMetabox",value:function(e){if(this.metaboxField){var t=this.getOptions().map((function(t){var r=t.value==e?'selected="selected"':"";return'<option value="'.concat(t.value,'" ').concat(r,">").concat(t.label,"</option>")}));this.metaboxField.value=e,this.metaboxField.innerHTML=t.join("")}}},{key:"getOptions",value:function(){return[{value:"none",label:(0,e.__)("None (will disable this feature)","wp-seopress")}].concat(function(e){if(Array.isArray(e))return a(e)}(t=this.state.selectableTerms.map((function(e){return{value:e.id,label:e.name}})))||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(t)||function(e,t){if(e){if("string"==typeof e)return a(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?a(e,t):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}());var t}},{key:"onChange",value:function(e){this.setState({primaryTermId:e})}},{key:"render",value:function(){return!!this.state.selectableTerms.length&&React.createElement(n.SelectControl,{label:(0,e.__)("Select a primary category","wp-seopress"),value:this.state.primaryTermId,options:this.getOptions(),onChange:this.onChange})}}])&&s(r.prototype,o),Object.defineProperty(r,"prototype",{writable:!1}),y}(t.Component),f=(0,r.withSelect)((function(e,t){var r=t.slug,n=e("core").getTaxonomy(r),o=n?e("core/editor").getEditedPostAttribute(n.rest_base):[];return{taxonomy:n,allTerms:e("core").getEntityRecords("taxonomy",r,{per_page:-1})||[],primaryTermId:e("core/editor").getEditedPostAttribute("meta")._seopress_robots_primary_cat||"none",selectedTermIds:o}}))(m);wp.hooks.addFilter("editor.PostTaxonomyType","wpseopress",(function(e){return function(t){return React.createElement(React.Fragment,null,React.createElement(e,t),t.slug&&"category"===t.slug&&React.createElement(n.PanelRow,{className:"seopress-primary-term-picker"},React.createElement(f,t)))}}))}();
readme.txt CHANGED
@@ -6,11 +6,11 @@ Tags: SEO, schema, xml sitemap, redirection, meta title, open graph, content ana
6
  Requires at least: 4.7+
7
  Tested up to: 6.0
8
  Requires PHP: 7.2
9
- Stable tag: 5.8.0.4
10
  License: GPLv2 or later
11
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
12
 
13
- Rank higher in search engines with SEOPress, a simple, fast and powerful all in one SEO plugin for WordPress. No ads, no footprints, no anonymous data sent, white label.
14
 
15
  == Description ==
16
 
@@ -197,6 +197,7 @@ SEOPress is translated into multiple languages including:
197
  <li>🇨🇳 中文 (Chinese (China)) - professional translation</li>
198
  <li>🇧🇷 Português do Brasil (Portuguese (Brazil)) - professional translation</li>
199
  <li>🇵🇱 Polskie (Polish) - professional translation</li>
 
200
  <li>🇬🇷 Ελληνικά (Greek)</li>
201
  <li>🇧🇬 Български (Bulgarian)</li>
202
  <li>🇮🇩 Bahasa Indonesia (Indonesian)</li>
@@ -362,6 +363,10 @@ You're theme is probably using a deprecated function to handle the title. <a hre
362
  12. Schema metabox
363
 
364
  == Changelog ==
 
 
 
 
365
  = 5.8.0.4 =
366
  * FIX Fatal error in Content Analysis metabox causing jQuery errors (thanks to @polishdreamer)
367
  = 5.8.0.3 =
6
  Requires at least: 4.7+
7
  Tested up to: 6.0
8
  Requires PHP: 7.2
9
+ Stable tag: 5.8.0.5
10
  License: GPLv2 or later
11
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
12
 
13
+ SEOPress, a simple, fast and powerful all in one SEO plugin for WordPress. Rank higher in search engines, fully white label.
14
 
15
  == Description ==
16
 
197
  <li>🇨🇳 中文 (Chinese (China)) - professional translation</li>
198
  <li>🇧🇷 Português do Brasil (Portuguese (Brazil)) - professional translation</li>
199
  <li>🇵🇱 Polskie (Polish) - professional translation</li>
200
+ <li>🇸🇪 Svenska (Swedish) - professional translation</li>
201
  <li>🇬🇷 Ελληνικά (Greek)</li>
202
  <li>🇧🇬 Български (Bulgarian)</li>
203
  <li>🇮🇩 Bahasa Indonesia (Indonesian)</li>
363
  12. Schema metabox
364
 
365
  == Changelog ==
366
+ = 5.8.0.5 =
367
+ * FIX Downgrade Google Auth API to prevent errors with hosting using PHP parser
368
+ * FIX "Sorry, you do not have permission to edit the _seopress_robots_primary_cat custom field." error
369
+ * FIX Remove "Inspect URL with Google" tab from Universal SEO metabox if disabled
370
  = 5.8.0.4 =
371
  * FIX Fatal error in Content Analysis metabox causing jQuery errors (thanks to @polishdreamer)
372
  = 5.8.0.3 =
seopress-functions.php CHANGED
@@ -296,17 +296,21 @@ function seopress_get_empty_templates($type, $metadata, $notice = true) {
296
 
297
  if (!empty($options)) {
298
  if ('cpt' === $type) {
299
- if (!array_key_exists($key, $options['seopress_titles_single_titles'])) {
300
- $cpt_titles_empty[] = $key;
301
- } else {
302
- $data = isset($options['seopress_titles_single_titles'][$key][$metadata]) ? $options['seopress_titles_single_titles'][$key][$metadata] : '';
 
 
303
  }
304
  }
305
  if ('tax' === $type) {
306
- if (!array_key_exists($key, $options['seopress_titles_tax_titles'])) {
307
- $cpt_titles_empty[] = $key;
308
- } else {
309
- $data = isset($options['seopress_titles_tax_titles'][$key][$metadata]) ? $options['seopress_titles_tax_titles'][$key][$metadata] : '';
 
 
310
  }
311
  }
312
  }
296
 
297
  if (!empty($options)) {
298
  if ('cpt' === $type) {
299
+ if (!empty($options['seopress_titles_single_titles'])) {
300
+ if (!array_key_exists($key, $options['seopress_titles_single_titles'])) {
301
+ $cpt_titles_empty[] = $key;
302
+ } else {
303
+ $data = isset($options['seopress_titles_single_titles'][$key][$metadata]) ? $options['seopress_titles_single_titles'][$key][$metadata] : '';
304
+ }
305
  }
306
  }
307
  if ('tax' === $type) {
308
+ if (!empty($options['seopress_titles_tax_titles'])) {
309
+ if (!array_key_exists($key, $options['seopress_titles_tax_titles'])) {
310
+ $cpt_titles_empty[] = $key;
311
+ } else {
312
+ $data = isset($options['seopress_titles_tax_titles'][$key][$metadata]) ? $options['seopress_titles_tax_titles'][$key][$metadata] : '';
313
+ }
314
  }
315
  }
316
  }
seopress.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: SEOPress
4
  Plugin URI: https://www.seopress.org/
5
  Description: One of the best SEO plugins for WordPress.
6
  Author: SEOPress
7
- Version: 5.8.0.4
8
  Author URI: https://www.seopress.org/
9
  License: GPLv2
10
  Text Domain: wp-seopress
@@ -70,7 +70,7 @@ register_deactivation_hook(__FILE__, 'seopress_deactivation');
70
  ///////////////////////////////////////////////////////////////////////////////////////////////////
71
  //Define
72
  ///////////////////////////////////////////////////////////////////////////////////////////////////
73
- define('SEOPRESS_VERSION', '5.8.0.4');
74
  define('SEOPRESS_AUTHOR', 'Benjamin Denis');
75
  define('SEOPRESS_PLUGIN_DIR_PATH', plugin_dir_path(__FILE__));
76
  define('SEOPRESS_PLUGIN_DIR_URL', plugin_dir_url(__FILE__));
@@ -80,7 +80,7 @@ define('SEOPRESS_TEMPLATE_SITEMAP_DIR', SEOPRESS_TEMPLATE_DIR . '/sitemap');
80
  define('SEOPRESS_TEMPLATE_JSON_SCHEMAS', SEOPRESS_TEMPLATE_DIR . '/json-schemas');
81
 
82
  define('SEOPRESS_DIRURL', plugin_dir_url(__FILE__));
83
- define('SEOPRESS_URL_DIST', SEOPRESS_DIRURL . 'public');
84
  define('SEOPRESS_URL_ASSETS', SEOPRESS_DIRURL . 'assets');
85
  define('SEOPRESS_DIR_LANGUAGES', dirname(plugin_basename(__FILE__)) . '/languages/');
86
 
4
  Plugin URI: https://www.seopress.org/
5
  Description: One of the best SEO plugins for WordPress.
6
  Author: SEOPress
7
+ Version: 5.8.0.5
8
  Author URI: https://www.seopress.org/
9
  License: GPLv2
10
  Text Domain: wp-seopress
70
  ///////////////////////////////////////////////////////////////////////////////////////////////////
71
  //Define
72
  ///////////////////////////////////////////////////////////////////////////////////////////////////
73
+ define('SEOPRESS_VERSION', '5.8.0.5');
74
  define('SEOPRESS_AUTHOR', 'Benjamin Denis');
75
  define('SEOPRESS_PLUGIN_DIR_PATH', plugin_dir_path(__FILE__));
76
  define('SEOPRESS_PLUGIN_DIR_URL', plugin_dir_url(__FILE__));
80
  define('SEOPRESS_TEMPLATE_JSON_SCHEMAS', SEOPRESS_TEMPLATE_DIR . '/json-schemas');
81
 
82
  define('SEOPRESS_DIRURL', plugin_dir_url(__FILE__));
83
+ define('SEOPRESS_URL_PUBLIC', SEOPRESS_DIRURL . 'public');
84
  define('SEOPRESS_URL_ASSETS', SEOPRESS_DIRURL . 'assets');
85
  define('SEOPRESS_DIR_LANGUAGES', dirname(plugin_basename(__FILE__)) . '/languages/');
86
 
src/Actions/Admin/ModuleMetabox.php CHANGED
@@ -52,7 +52,7 @@ class ModuleMetabox implements ExecuteHooks
52
  }
53
 
54
  wp_enqueue_media();
55
- wp_enqueue_script('seopress-metabox', SEOPRESS_URL_DIST . '/metaboxe.js', $dependencies, SEOPRESS_VERSION, true);
56
  $value = wp_create_nonce('seopress_rest');
57
 
58
  $tags = seopress_get_service('TagsToString')->getTagsAvailable([
@@ -79,7 +79,7 @@ class ModuleMetabox implements ExecuteHooks
79
  $roles = ( array ) $user->roles;
80
 
81
  $args = array_merge([
82
- 'SEOPRESS_URL_DIST' => SEOPRESS_URL_DIST,
83
  'SEOPRESS_URL_ASSETS' => SEOPRESS_URL_ASSETS,
84
  'SITENAME' => get_bloginfo('name'),
85
  'SITEURL' => site_url(),
52
  }
53
 
54
  wp_enqueue_media();
55
+ wp_enqueue_script('seopress-metabox', SEOPRESS_URL_PUBLIC . '/metaboxe.js', $dependencies, SEOPRESS_VERSION, true);
56
  $value = wp_create_nonce('seopress_rest');
57
 
58
  $tags = seopress_get_service('TagsToString')->getTagsAvailable([
79
  $roles = ( array ) $user->roles;
80
 
81
  $args = array_merge([
82
+ 'SEOPRESS_URL_PUBLIC' => SEOPRESS_URL_PUBLIC,
83
  'SEOPRESS_URL_ASSETS' => SEOPRESS_URL_ASSETS,
84
  'SITENAME' => get_bloginfo('name'),
85
  'SITEURL' => site_url(),
src/Actions/Api/Metas/AdvancedSettings.php CHANGED
@@ -1,13 +1,35 @@
1
  <?php
 
2
 
3
  if (! defined('ABSPATH')) {
4
  exit;
5
  }
6
 
7
- register_post_meta( 'post', '_seopress_robots_primary_cat',
8
- [
9
- 'show_in_rest' => true,
10
- 'single' => true,
11
- 'type' => 'string',
12
- ]
13
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
+ namespace SEOPress\Actions\Api\Metas;
3
 
4
  if (! defined('ABSPATH')) {
5
  exit;
6
  }
7
 
8
+ use SEOPress\Core\Hooks\ExecuteHooks;
9
+
10
+ class AdvancedSettings implements ExecuteHooks
11
+ {
12
+ public function hooks() {
13
+ register_post_meta( '', '_seopress_robots_primary_cat',
14
+ [
15
+ 'show_in_rest' => true,
16
+ 'single' => true,
17
+ 'type' => 'string',
18
+ 'auth_callback' => [$this, 'meta_auth']
19
+ ]
20
+ );
21
+ }
22
+
23
+ /**
24
+ * Auth callback is required for protected meta keys
25
+ *
26
+ * @param bool $allowed
27
+ * @param string $meta_key
28
+ * @param int $id
29
+ * @return bool $allowed
30
+ */
31
+ public function meta_auth( $allowed, $meta_key, $id ) {
32
+ return current_user_can( 'edit_posts', $id );
33
+ }
34
+ }
35
+
src/Services/Options/ToggleOption.php CHANGED
@@ -50,4 +50,8 @@ class ToggleOption {
50
  public function getToggleGoogleNews(){
51
  return $this->searchOptionByKey('news');
52
  }
 
 
 
 
53
  }
50
  public function getToggleGoogleNews(){
51
  return $this->searchOptionByKey('news');
52
  }
53
+
54
+ public function getToggleInspectUrl(){
55
+ return $this->searchOptionByKey('inspect-url');
56
+ }
57
  }
vendor/composer/installed.json CHANGED
@@ -2,34 +2,29 @@
2
  "packages": [
3
  {
4
  "name": "firebase/php-jwt",
5
- "version": "v6.2.0",
6
- "version_normalized": "6.2.0.0",
7
  "source": {
8
  "type": "git",
9
  "url": "https://github.com/firebase/php-jwt.git",
10
- "reference": "d28e6df83830252650da4623c78aaaf98fb385f3"
11
  },
12
  "dist": {
13
  "type": "zip",
14
- "url": "https://api.github.com/repos/firebase/php-jwt/zipball/d28e6df83830252650da4623c78aaaf98fb385f3",
15
- "reference": "d28e6df83830252650da4623c78aaaf98fb385f3",
16
  "shasum": ""
17
  },
18
  "require": {
19
- "php": "^7.1||^8.0"
20
  },
21
  "require-dev": {
22
- "guzzlehttp/guzzle": "^6.5||^7.4",
23
- "phpspec/prophecy-phpunit": "^1.1",
24
- "phpunit/phpunit": "^7.5||^9.5",
25
- "psr/cache": "^1.0||^2.0",
26
- "psr/http-client": "^1.0",
27
- "psr/http-factory": "^1.0"
28
  },
29
  "suggest": {
30
  "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
31
  },
32
- "time": "2022-05-13T20:54:50+00:00",
33
  "type": "library",
34
  "installation-source": "dist",
35
  "autoload": {
@@ -61,7 +56,7 @@
61
  ],
62
  "support": {
63
  "issues": "https://github.com/firebase/php-jwt/issues",
64
- "source": "https://github.com/firebase/php-jwt/tree/v6.2.0"
65
  },
66
  "install-path": "../firebase/php-jwt"
67
  },
@@ -187,25 +182,25 @@
187
  },
188
  {
189
  "name": "google/auth",
190
- "version": "v1.21.1",
191
- "version_normalized": "1.21.1.0",
192
  "source": {
193
  "type": "git",
194
  "url": "https://github.com/googleapis/google-auth-library-php.git",
195
- "reference": "aa3b9ca29258ac6347ce3c8937a2418c5d78f840"
196
  },
197
  "dist": {
198
  "type": "zip",
199
- "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/aa3b9ca29258ac6347ce3c8937a2418c5d78f840",
200
- "reference": "aa3b9ca29258ac6347ce3c8937a2418c5d78f840",
201
  "shasum": ""
202
  },
203
  "require": {
204
- "firebase/php-jwt": "^5.5||^6.0",
205
  "guzzlehttp/guzzle": "^6.2.1|^7.0",
206
  "guzzlehttp/psr7": "^1.7|^2.0",
207
- "php": "^7.1||^8.0",
208
- "psr/cache": "^1.0|^2.0|^3.0",
209
  "psr/http-message": "^1.0"
210
  },
211
  "require-dev": {
@@ -213,14 +208,14 @@
213
  "kelvinmo/simplejwt": "^0.2.5|^0.5.1",
214
  "phpseclib/phpseclib": "^2.0.31",
215
  "phpspec/prophecy-phpunit": "^1.1",
216
- "phpunit/phpunit": "^7.5||^8.5",
217
  "sebastian/comparator": ">=1.2.3",
218
  "squizlabs/php_codesniffer": "^3.5"
219
  },
220
  "suggest": {
221
  "phpseclib/phpseclib": "May be used in place of OpenSSL for signing strings or for token management. Please require version ^2."
222
  },
223
- "time": "2022-05-16T19:34:15+00:00",
224
  "type": "library",
225
  "installation-source": "dist",
226
  "autoload": {
@@ -242,7 +237,7 @@
242
  "support": {
243
  "docs": "https://googleapis.github.io/google-auth-library-php/main/",
244
  "issues": "https://github.com/googleapis/google-auth-library-php/issues",
245
- "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.21.1"
246
  },
247
  "install-path": "../google/auth"
248
  },
2
  "packages": [
3
  {
4
  "name": "firebase/php-jwt",
5
+ "version": "v5.5.1",
6
+ "version_normalized": "5.5.1.0",
7
  "source": {
8
  "type": "git",
9
  "url": "https://github.com/firebase/php-jwt.git",
10
+ "reference": "83b609028194aa042ea33b5af2d41a7427de80e6"
11
  },
12
  "dist": {
13
  "type": "zip",
14
+ "url": "https://api.github.com/repos/firebase/php-jwt/zipball/83b609028194aa042ea33b5af2d41a7427de80e6",
15
+ "reference": "83b609028194aa042ea33b5af2d41a7427de80e6",
16
  "shasum": ""
17
  },
18
  "require": {
19
+ "php": ">=5.3.0"
20
  },
21
  "require-dev": {
22
+ "phpunit/phpunit": ">=4.8 <=9"
 
 
 
 
 
23
  },
24
  "suggest": {
25
  "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
26
  },
27
+ "time": "2021-11-08T20:18:51+00:00",
28
  "type": "library",
29
  "installation-source": "dist",
30
  "autoload": {
56
  ],
57
  "support": {
58
  "issues": "https://github.com/firebase/php-jwt/issues",
59
+ "source": "https://github.com/firebase/php-jwt/tree/v5.5.1"
60
  },
61
  "install-path": "../firebase/php-jwt"
62
  },
182
  },
183
  {
184
  "name": "google/auth",
185
+ "version": "v1.19.0",
186
+ "version_normalized": "1.19.0.0",
187
  "source": {
188
  "type": "git",
189
  "url": "https://github.com/googleapis/google-auth-library-php.git",
190
+ "reference": "31e5d24d5fa0eaf6adc7e596292dc4732f4b60c5"
191
  },
192
  "dist": {
193
  "type": "zip",
194
+ "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/31e5d24d5fa0eaf6adc7e596292dc4732f4b60c5",
195
+ "reference": "31e5d24d5fa0eaf6adc7e596292dc4732f4b60c5",
196
  "shasum": ""
197
  },
198
  "require": {
199
+ "firebase/php-jwt": "~5.0",
200
  "guzzlehttp/guzzle": "^6.2.1|^7.0",
201
  "guzzlehttp/psr7": "^1.7|^2.0",
202
+ "php": ">=5.6",
203
+ "psr/cache": "^1.0|^2.0",
204
  "psr/http-message": "^1.0"
205
  },
206
  "require-dev": {
208
  "kelvinmo/simplejwt": "^0.2.5|^0.5.1",
209
  "phpseclib/phpseclib": "^2.0.31",
210
  "phpspec/prophecy-phpunit": "^1.1",
211
+ "phpunit/phpunit": "^5.7||^8.5.13",
212
  "sebastian/comparator": ">=1.2.3",
213
  "squizlabs/php_codesniffer": "^3.5"
214
  },
215
  "suggest": {
216
  "phpseclib/phpseclib": "May be used in place of OpenSSL for signing strings or for token management. Please require version ^2."
217
  },
218
+ "time": "2022-03-24T21:22:45+00:00",
219
  "type": "library",
220
  "installation-source": "dist",
221
  "autoload": {
237
  "support": {
238
  "docs": "https://googleapis.github.io/google-auth-library-php/main/",
239
  "issues": "https://github.com/googleapis/google-auth-library-php/issues",
240
+ "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.19.0"
241
  },
242
  "install-path": "../google/auth"
243
  },
vendor/composer/installed.php CHANGED
@@ -5,18 +5,18 @@
5
  'type' => 'wordpress-plugin',
6
  'install_path' => __DIR__ . '/../../',
7
  'aliases' => array(),
8
- 'reference' => '310d9c980328e339c78bf366a50d8e68d40df13e',
9
  'name' => 'wp-seopress/wp-seopress',
10
  'dev' => false,
11
  ),
12
  'versions' => array(
13
  'firebase/php-jwt' => array(
14
- 'pretty_version' => 'v6.2.0',
15
- 'version' => '6.2.0.0',
16
  'type' => 'library',
17
  'install_path' => __DIR__ . '/../firebase/php-jwt',
18
  'aliases' => array(),
19
- 'reference' => 'd28e6df83830252650da4623c78aaaf98fb385f3',
20
  'dev_requirement' => false,
21
  ),
22
  'google/apiclient' => array(
@@ -38,12 +38,12 @@
38
  'dev_requirement' => false,
39
  ),
40
  'google/auth' => array(
41
- 'pretty_version' => 'v1.21.1',
42
- 'version' => '1.21.1.0',
43
  'type' => 'library',
44
  'install_path' => __DIR__ . '/../google/auth',
45
  'aliases' => array(),
46
- 'reference' => 'aa3b9ca29258ac6347ce3c8937a2418c5d78f840',
47
  'dev_requirement' => false,
48
  ),
49
  'guzzlehttp/guzzle' => array(
@@ -202,7 +202,7 @@
202
  'type' => 'wordpress-plugin',
203
  'install_path' => __DIR__ . '/../../',
204
  'aliases' => array(),
205
- 'reference' => '310d9c980328e339c78bf366a50d8e68d40df13e',
206
  'dev_requirement' => false,
207
  ),
208
  ),
5
  'type' => 'wordpress-plugin',
6
  'install_path' => __DIR__ . '/../../',
7
  'aliases' => array(),
8
+ 'reference' => '1523eaa70848c3e9e7fe4c463b934193152fdbfe',
9
  'name' => 'wp-seopress/wp-seopress',
10
  'dev' => false,
11
  ),
12
  'versions' => array(
13
  'firebase/php-jwt' => array(
14
+ 'pretty_version' => 'v5.5.1',
15
+ 'version' => '5.5.1.0',
16
  'type' => 'library',
17
  'install_path' => __DIR__ . '/../firebase/php-jwt',
18
  'aliases' => array(),
19
+ 'reference' => '83b609028194aa042ea33b5af2d41a7427de80e6',
20
  'dev_requirement' => false,
21
  ),
22
  'google/apiclient' => array(
38
  'dev_requirement' => false,
39
  ),
40
  'google/auth' => array(
41
+ 'pretty_version' => 'v1.19.0',
42
+ 'version' => '1.19.0.0',
43
  'type' => 'library',
44
  'install_path' => __DIR__ . '/../google/auth',
45
  'aliases' => array(),
46
+ 'reference' => '31e5d24d5fa0eaf6adc7e596292dc4732f4b60c5',
47
  'dev_requirement' => false,
48
  ),
49
  'guzzlehttp/guzzle' => array(
202
  'type' => 'wordpress-plugin',
203
  'install_path' => __DIR__ . '/../../',
204
  'aliases' => array(),
205
+ 'reference' => '1523eaa70848c3e9e7fe4c463b934193152fdbfe',
206
  'dev_requirement' => false,
207
  ),
208
  ),
vendor/firebase/php-jwt/README.md CHANGED
@@ -1,4 +1,4 @@
1
- ![Build Status](https://github.com/firebase/php-jwt/actions/workflows/tests.yml/badge.svg)
2
  [![Latest Stable Version](https://poser.pugx.org/firebase/php-jwt/v/stable)](https://packagist.org/packages/firebase/php-jwt)
3
  [![Total Downloads](https://poser.pugx.org/firebase/php-jwt/downloads)](https://packagist.org/packages/firebase/php-jwt)
4
  [![License](https://poser.pugx.org/firebase/php-jwt/license)](https://packagist.org/packages/firebase/php-jwt)
@@ -29,13 +29,13 @@ Example
29
  use Firebase\JWT\JWT;
30
  use Firebase\JWT\Key;
31
 
32
- $key = 'example_key';
33
- $payload = [
34
- 'iss' => 'http://example.org',
35
- 'aud' => 'http://example.com',
36
- 'iat' => 1356999524,
37
- 'nbf' => 1357000000
38
- ];
39
 
40
  /**
41
  * IMPORTANT:
@@ -98,12 +98,12 @@ ehde/zUxo6UvS7UrBQIDAQAB
98
  -----END PUBLIC KEY-----
99
  EOD;
100
 
101
- $payload = [
102
- 'iss' => 'example.org',
103
- 'aud' => 'example.com',
104
- 'iat' => 1356999524,
105
- 'nbf' => 1357000000
106
- ];
107
 
108
  $jwt = JWT::encode($payload, $privateKey, 'RS256');
109
  echo "Encode:\n" . print_r($jwt, true) . "\n";
@@ -139,12 +139,12 @@ $privateKey = openssl_pkey_get_private(
139
  $passphrase
140
  );
141
 
142
- $payload = [
143
- 'iss' => 'example.org',
144
- 'aud' => 'example.com',
145
- 'iat' => 1356999524,
146
- 'nbf' => 1357000000
147
- ];
148
 
149
  $jwt = JWT::encode($payload, $privateKey, 'RS256');
150
  echo "Encode:\n" . print_r($jwt, true) . "\n";
@@ -173,12 +173,12 @@ $privateKey = base64_encode(sodium_crypto_sign_secretkey($keyPair));
173
 
174
  $publicKey = base64_encode(sodium_crypto_sign_publickey($keyPair));
175
 
176
- $payload = [
177
- 'iss' => 'example.org',
178
- 'aud' => 'example.com',
179
- 'iat' => 1356999524,
180
- 'nbf' => 1357000000
181
- ];
182
 
183
  $jwt = JWT::encode($payload, $privateKey, 'EdDSA');
184
  echo "Encode:\n" . print_r($jwt, true) . "\n";
@@ -198,83 +198,15 @@ use Firebase\JWT\JWT;
198
  // this endpoint: https://www.gstatic.com/iap/verify/public_key-jwk
199
  $jwks = ['keys' => []];
200
 
201
- // JWK::parseKeySet($jwks) returns an associative array of **kid** to Firebase\JWT\Key
202
- // objects. Pass this as the second parameter to JWT::decode.
203
- JWT::decode($payload, JWK::parseKeySet($jwks));
204
- ```
205
-
206
- Using Cached Key Sets
207
- ---------------------
208
-
209
- The `CachedKeySet` class can be used to fetch and cache JWKS (JSON Web Key Sets) from a public URI.
210
- This has the following advantages:
211
-
212
- 1. The results are cached for performance.
213
- 2. If an unrecognized key is requested, the cache is refreshed, to accomodate for key rotation.
214
- 3. If rate limiting is enabled, the JWKS URI will not make more than 10 requests a second.
215
-
216
- ```php
217
- use Firebase\JWT\CachedKeySet;
218
- use Firebase\JWT\JWT;
219
-
220
- // The URI for the JWKS you wish to cache the results from
221
- $jwksUri = 'https://www.gstatic.com/iap/verify/public_key-jwk';
222
-
223
- // Create an HTTP client (can be any PSR-7 compatible HTTP client)
224
- $httpClient = new GuzzleHttp\Client();
225
-
226
- // Create an HTTP request factory (can be any PSR-17 compatible HTTP request factory)
227
- $httpFactory = new GuzzleHttp\Psr\HttpFactory();
228
-
229
- // Create a cache item pool (can be any PSR-6 compatible cache item pool)
230
- $cacheItemPool = Phpfastcache\CacheManager::getInstance('files');
231
-
232
- $keySet = new CachedKeySet(
233
- $jwksUri,
234
- $httpClient,
235
- $httpFactory,
236
- $cacheItemPool,
237
- null, // $expiresAfter int seconds to set the JWKS to expire
238
- true // $rateLimit true to enable rate limit of 10 RPS on lookup of invalid keys
239
- );
240
-
241
- $jwt = 'eyJhbGci...'; // Some JWT signed by a key from the $jwkUri above
242
- $decoded = JWT::decode($jwt, $keySet);
243
- ```
244
-
245
- Miscellaneous
246
- -------------
247
-
248
- #### Casting to array
249
-
250
- The return value of `JWT::decode` is the generic PHP object `stdClass`. If you'd like to handle with arrays
251
- instead, you can do the following:
252
-
253
- ```php
254
- // return type is stdClass
255
- $decoded = JWT::decode($payload, $keys);
256
-
257
- // cast to array
258
- $decoded = json_decode(json_encode($decoded), true);
259
  ```
260
 
261
  Changelog
262
  ---------
263
 
264
- #### 6.1.0 / 2022-03-23
265
-
266
- - Drop support for PHP 5.3, 5.4, 5.5, 5.6, and 7.0
267
- - Add parameter typing and return types where possible
268
-
269
- #### 6.0.0 / 2022-01-24
270
-
271
- - **Backwards-Compatibility Breaking Changes**: See the [Release Notes](https://github.com/firebase/php-jwt/releases/tag/v6.0.0) for more information.
272
- - New Key object to prevent key/algorithm type confusion (#365)
273
- - Add JWK support (#273)
274
- - Add ES256 support (#256)
275
- - Add ES384 support (#324)
276
- - Add Ed25519 support (#343)
277
-
278
  #### 5.0.0 / 2017-06-26
279
  - Support RS384 and RS512.
280
  See [#117](https://github.com/firebase/php-jwt/pull/117). Thanks [@joostfaassen](https://github.com/joostfaassen)!
1
+ [![Build Status](https://travis-ci.org/firebase/php-jwt.png?branch=master)](https://travis-ci.org/firebase/php-jwt)
2
  [![Latest Stable Version](https://poser.pugx.org/firebase/php-jwt/v/stable)](https://packagist.org/packages/firebase/php-jwt)
3
  [![Total Downloads](https://poser.pugx.org/firebase/php-jwt/downloads)](https://packagist.org/packages/firebase/php-jwt)
4
  [![License](https://poser.pugx.org/firebase/php-jwt/license)](https://packagist.org/packages/firebase/php-jwt)
29
  use Firebase\JWT\JWT;
30
  use Firebase\JWT\Key;
31
 
32
+ $key = "example_key";
33
+ $payload = array(
34
+ "iss" => "http://example.org",
35
+ "aud" => "http://example.com",
36
+ "iat" => 1356999524,
37
+ "nbf" => 1357000000
38
+ );
39
 
40
  /**
41
  * IMPORTANT:
98
  -----END PUBLIC KEY-----
99
  EOD;
100
 
101
+ $payload = array(
102
+ "iss" => "example.org",
103
+ "aud" => "example.com",
104
+ "iat" => 1356999524,
105
+ "nbf" => 1357000000
106
+ );
107
 
108
  $jwt = JWT::encode($payload, $privateKey, 'RS256');
109
  echo "Encode:\n" . print_r($jwt, true) . "\n";
139
  $passphrase
140
  );
141
 
142
+ $payload = array(
143
+ "iss" => "example.org",
144
+ "aud" => "example.com",
145
+ "iat" => 1356999524,
146
+ "nbf" => 1357000000
147
+ );
148
 
149
  $jwt = JWT::encode($payload, $privateKey, 'RS256');
150
  echo "Encode:\n" . print_r($jwt, true) . "\n";
173
 
174
  $publicKey = base64_encode(sodium_crypto_sign_publickey($keyPair));
175
 
176
+ $payload = array(
177
+ "iss" => "example.org",
178
+ "aud" => "example.com",
179
+ "iat" => 1356999524,
180
+ "nbf" => 1357000000
181
+ );
182
 
183
  $jwt = JWT::encode($payload, $privateKey, 'EdDSA');
184
  echo "Encode:\n" . print_r($jwt, true) . "\n";
198
  // this endpoint: https://www.gstatic.com/iap/verify/public_key-jwk
199
  $jwks = ['keys' => []];
200
 
201
+ // JWK::parseKeySet($jwks) returns an associative array of **kid** to private
202
+ // key. Pass this as the second parameter to JWT::decode.
203
+ // NOTE: The deprecated $supportedAlgorithm must be supplied when parsing from JWK.
204
+ JWT::decode($payload, JWK::parseKeySet($jwks), $supportedAlgorithm);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  ```
206
 
207
  Changelog
208
  ---------
209
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
  #### 5.0.0 / 2017-06-26
211
  - Support RS384 and RS512.
212
  See [#117](https://github.com/firebase/php-jwt/pull/117). Thanks [@joostfaassen](https://github.com/joostfaassen)!
vendor/firebase/php-jwt/composer.json CHANGED
@@ -20,7 +20,7 @@
20
  ],
21
  "license": "BSD-3-Clause",
22
  "require": {
23
- "php": "^7.1||^8.0"
24
  },
25
  "suggest": {
26
  "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
@@ -31,11 +31,6 @@
31
  }
32
  },
33
  "require-dev": {
34
- "guzzlehttp/guzzle": "^6.5||^7.4",
35
- "phpspec/prophecy-phpunit": "^1.1",
36
- "phpunit/phpunit": "^7.5||^9.5",
37
- "psr/cache": "^1.0||^2.0",
38
- "psr/http-client": "^1.0",
39
- "psr/http-factory": "^1.0"
40
  }
41
  }
20
  ],
21
  "license": "BSD-3-Clause",
22
  "require": {
23
+ "php": ">=5.3.0"
24
  },
25
  "suggest": {
26
  "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
31
  }
32
  },
33
  "require-dev": {
34
+ "phpunit/phpunit": ">=4.8 <=9"
 
 
 
 
 
35
  }
36
  }
vendor/firebase/php-jwt/src/CachedKeySet.php DELETED
@@ -1,231 +0,0 @@
1
- <?php
2
-
3
- namespace Firebase\JWT;
4
-
5
- use ArrayAccess;
6
- use LogicException;
7
- use OutOfBoundsException;
8
- use Psr\Cache\CacheItemInterface;
9
- use Psr\Cache\CacheItemPoolInterface;
10
- use Psr\Http\Client\ClientInterface;
11
- use Psr\Http\Message\RequestFactoryInterface;
12
- use RuntimeException;
13
-
14
- /**
15
- * @implements ArrayAccess<string, Key>
16
- */
17
- class CachedKeySet implements ArrayAccess
18
- {
19
- /**
20
- * @var string
21
- */
22
- private $jwksUri;
23
- /**
24
- * @var ClientInterface
25
- */
26
- private $httpClient;
27
- /**
28
- * @var RequestFactoryInterface
29
- */
30
- private $httpFactory;
31
- /**
32
- * @var CacheItemPoolInterface
33
- */
34
- private $cache;
35
- /**
36
- * @var ?int
37
- */
38
- private $expiresAfter;
39
- /**
40
- * @var ?CacheItemInterface
41
- */
42
- private $cacheItem;
43
- /**
44
- * @var array<string, Key>
45
- */
46
- private $keySet;
47
- /**
48
- * @var string
49
- */
50
- private $cacheKey;
51
- /**
52
- * @var string
53
- */
54
- private $cacheKeyPrefix = 'jwks';
55
- /**
56
- * @var int
57
- */
58
- private $maxKeyLength = 64;
59
- /**
60
- * @var bool
61
- */
62
- private $rateLimit;
63
- /**
64
- * @var string
65
- */
66
- private $rateLimitCacheKey;
67
- /**
68
- * @var int
69
- */
70
- private $maxCallsPerMinute = 10;
71
- /**
72
- * @var string|null
73
- */
74
- private $defaultAlg;
75
-
76
- public function __construct(
77
- string $jwksUri,
78
- ClientInterface $httpClient,
79
- RequestFactoryInterface $httpFactory,
80
- CacheItemPoolInterface $cache,
81
- int $expiresAfter = null,
82
- bool $rateLimit = false,
83
- string $defaultAlg = null
84
- ) {
85
- $this->jwksUri = $jwksUri;
86
- $this->httpClient = $httpClient;
87
- $this->httpFactory = $httpFactory;
88
- $this->cache = $cache;
89
- $this->expiresAfter = $expiresAfter;
90
- $this->rateLimit = $rateLimit;
91
- $this->defaultAlg = $defaultAlg;
92
- $this->setCacheKeys();
93
- }
94
-
95
- /**
96
- * @param string $keyId
97
- * @return Key
98
- */
99
- public function offsetGet($keyId): Key
100
- {
101
- if (!$this->keyIdExists($keyId)) {
102
- throw new OutOfBoundsException('Key ID not found');
103
- }
104
- return $this->keySet[$keyId];
105
- }
106
-
107
- /**
108
- * @param string $keyId
109
- * @return bool
110
- */
111
- public function offsetExists($keyId): bool
112
- {
113
- return $this->keyIdExists($keyId);
114
- }
115
-
116
- /**
117
- * @param string $offset
118
- * @param Key $value
119
- */
120
- public function offsetSet($offset, $value): void
121
- {
122
- throw new LogicException('Method not implemented');
123
- }
124
-
125
- /**
126
- * @param string $offset
127
- */
128
- public function offsetUnset($offset): void
129
- {
130
- throw new LogicException('Method not implemented');
131
- }
132
-
133
- private function keyIdExists(string $keyId): bool
134
- {
135
- $keySetToCache = null;
136
- if (null === $this->keySet) {
137
- $item = $this->getCacheItem();
138
- // Try to load keys from cache
139
- if ($item->isHit()) {
140
- // item found! Return it
141
- $this->keySet = $item->get();
142
- }
143
- }
144
-
145
- if (!isset($this->keySet[$keyId])) {
146
- if ($this->rateLimitExceeded()) {
147
- return false;
148
- }
149
- $request = $this->httpFactory->createRequest('get', $this->jwksUri);
150
- $jwksResponse = $this->httpClient->sendRequest($request);
151
- $jwks = json_decode((string) $jwksResponse->getBody(), true);
152
- $this->keySet = $keySetToCache = JWK::parseKeySet($jwks, $this->defaultAlg);
153
-
154
- if (!isset($this->keySet[$keyId])) {
155
- return false;
156
- }
157
- }
158
-
159
- if ($keySetToCache) {
160
- $item = $this->getCacheItem();
161
- $item->set($keySetToCache);
162
- if ($this->expiresAfter) {
163
- $item->expiresAfter($this->expiresAfter);
164
- }
165
- $this->cache->save($item);
166
- }
167
-
168
- return true;
169
- }
170
-
171
- private function rateLimitExceeded(): bool
172
- {
173
- if (!$this->rateLimit) {
174
- return false;
175
- }
176
-
177
- $cacheItem = $this->cache->getItem($this->rateLimitCacheKey);
178
- if (!$cacheItem->isHit()) {
179
- $cacheItem->expiresAfter(1); // # of calls are cached each minute
180
- }
181
-
182
- $callsPerMinute = (int) $cacheItem->get();
183
- if (++$callsPerMinute > $this->maxCallsPerMinute) {
184
- return true;
185
- }
186
- $cacheItem->set($callsPerMinute);
187
- $this->cache->save($cacheItem);
188
- return false;
189
- }
190
-
191
- private function getCacheItem(): CacheItemInterface
192
- {
193
- if (\is_null($this->cacheItem)) {
194
- $this->cacheItem = $this->cache->getItem($this->cacheKey);
195
- }
196
-
197
- return $this->cacheItem;
198
- }
199
-
200
- private function setCacheKeys(): void
201
- {
202
- if (empty($this->jwksUri)) {
203
- throw new RuntimeException('JWKS URI is empty');
204
- }
205
-
206
- // ensure we do not have illegal characters
207
- $key = preg_replace('|[^a-zA-Z0-9_\.!]|', '', $this->jwksUri);
208
-
209
- // add prefix
210
- $key = $this->cacheKeyPrefix . $key;
211
-
212
- // Hash keys if they exceed $maxKeyLength of 64
213
- if (\strlen($key) > $this->maxKeyLength) {
214
- $key = substr(hash('sha256', $key), 0, $this->maxKeyLength);
215
- }
216
-
217
- $this->cacheKey = $key;
218
-
219
- if ($this->rateLimit) {
220
- // add prefix
221
- $rateLimitKey = $this->cacheKeyPrefix . 'ratelimit' . $key;
222
-
223
- // Hash keys if they exceed $maxKeyLength of 64
224
- if (\strlen($rateLimitKey) > $this->maxKeyLength) {
225
- $rateLimitKey = substr(hash('sha256', $rateLimitKey), 0, $this->maxKeyLength);
226
- }
227
-
228
- $this->rateLimitCacheKey = $rateLimitKey;
229
- }
230
- }
231
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/firebase/php-jwt/src/JWK.php CHANGED
@@ -23,11 +23,9 @@ class JWK
23
  /**
24
  * Parse a set of JWK keys
25
  *
26
- * @param array<mixed> $jwks The JSON Web Key Set as an associative array
27
- * @param string $defaultAlg The algorithm for the Key object if "alg" is not set in the
28
- * JSON Web Key Set
29
  *
30
- * @return array<string, Key> An associative array of key IDs (kid) to Key objects
31
  *
32
  * @throws InvalidArgumentException Provided JWK Set is empty
33
  * @throws UnexpectedValueException Provided JWK Set was invalid
@@ -35,22 +33,21 @@ class JWK
35
  *
36
  * @uses parseKey
37
  */
38
- public static function parseKeySet(array $jwks, string $defaultAlg = null): array
39
  {
40
- $keys = [];
41
 
42
  if (!isset($jwks['keys'])) {
43
  throw new UnexpectedValueException('"keys" member must exist in the JWK Set');
44
  }
45
-
46
  if (empty($jwks['keys'])) {
47
  throw new InvalidArgumentException('JWK Set did not contain any keys');
48
  }
49
 
50
  foreach ($jwks['keys'] as $k => $v) {
51
  $kid = isset($v['kid']) ? $v['kid'] : $k;
52
- if ($key = self::parseKey($v, $defaultAlg)) {
53
- $keys[(string) $kid] = $key;
54
  }
55
  }
56
 
@@ -64,11 +61,9 @@ class JWK
64
  /**
65
  * Parse a JWK key
66
  *
67
- * @param array<mixed> $jwk An individual JWK
68
- * @param string $defaultAlg The algorithm for the Key object if "alg" is not set in the
69
- * JSON Web Key Set
70
  *
71
- * @return Key The key object for the JWK
72
  *
73
  * @throws InvalidArgumentException Provided JWK is empty
74
  * @throws UnexpectedValueException Provided JWK was invalid
@@ -76,27 +71,15 @@ class JWK
76
  *
77
  * @uses createPemFromModulusAndExponent
78
  */
79
- public static function parseKey(array $jwk, string $defaultAlg = null): ?Key
80
  {
81
  if (empty($jwk)) {
82
  throw new InvalidArgumentException('JWK must not be empty');
83
  }
84
-
85
  if (!isset($jwk['kty'])) {
86
  throw new UnexpectedValueException('JWK must contain a "kty" parameter');
87
  }
88
 
89
- if (!isset($jwk['alg'])) {
90
- if (\is_null($defaultAlg)) {
91
- // The "alg" parameter is optional in a KTY, but an algorithm is required
92
- // for parsing in this library. Use the $defaultAlg parameter when parsing the
93
- // key set in order to prevent this error.
94
- // @see https://datatracker.ietf.org/doc/html/rfc7517#section-4.4
95
- throw new UnexpectedValueException('JWK must contain an "alg" parameter');
96
- }
97
- $jwk['alg'] = $defaultAlg;
98
- }
99
-
100
  switch ($jwk['kty']) {
101
  case 'RSA':
102
  if (!empty($jwk['d'])) {
@@ -113,13 +96,11 @@ class JWK
113
  'OpenSSL error: ' . \openssl_error_string()
114
  );
115
  }
116
- return new Key($publicKey, $jwk['alg']);
117
  default:
118
  // Currently only RSA is supported
119
  break;
120
  }
121
-
122
- return null;
123
  }
124
 
125
  /**
@@ -132,22 +113,22 @@ class JWK
132
  *
133
  * @uses encodeLength
134
  */
135
- private static function createPemFromModulusAndExponent(
136
- string $n,
137
- string $e
138
- ): string {
139
- $mod = JWT::urlsafeB64Decode($n);
140
- $exp = JWT::urlsafeB64Decode($e);
141
 
142
- $modulus = \pack('Ca*a*', 2, self::encodeLength(\strlen($mod)), $mod);
143
- $publicExponent = \pack('Ca*a*', 2, self::encodeLength(\strlen($exp)), $exp);
 
 
144
 
145
  $rsaPublicKey = \pack(
146
  'Ca*a*a*',
147
  48,
148
- self::encodeLength(\strlen($modulus) + \strlen($publicExponent)),
149
- $modulus,
150
- $publicExponent
151
  );
152
 
153
  // sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption.
@@ -178,7 +159,7 @@ class JWK
178
  * @param int $length
179
  * @return string
180
  */
181
- private static function encodeLength(int $length): string
182
  {
183
  if ($length <= 0x7F) {
184
  return \chr($length);
23
  /**
24
  * Parse a set of JWK keys
25
  *
26
+ * @param array $jwks The JSON Web Key Set as an associative array
 
 
27
  *
28
+ * @return array An associative array that represents the set of keys
29
  *
30
  * @throws InvalidArgumentException Provided JWK Set is empty
31
  * @throws UnexpectedValueException Provided JWK Set was invalid
33
  *
34
  * @uses parseKey
35
  */
36
+ public static function parseKeySet(array $jwks)
37
  {
38
+ $keys = array();
39
 
40
  if (!isset($jwks['keys'])) {
41
  throw new UnexpectedValueException('"keys" member must exist in the JWK Set');
42
  }
 
43
  if (empty($jwks['keys'])) {
44
  throw new InvalidArgumentException('JWK Set did not contain any keys');
45
  }
46
 
47
  foreach ($jwks['keys'] as $k => $v) {
48
  $kid = isset($v['kid']) ? $v['kid'] : $k;
49
+ if ($key = self::parseKey($v)) {
50
+ $keys[$kid] = $key;
51
  }
52
  }
53
 
61
  /**
62
  * Parse a JWK key
63
  *
64
+ * @param array $jwk An individual JWK
 
 
65
  *
66
+ * @return resource|array An associative array that represents the key
67
  *
68
  * @throws InvalidArgumentException Provided JWK is empty
69
  * @throws UnexpectedValueException Provided JWK was invalid
71
  *
72
  * @uses createPemFromModulusAndExponent
73
  */
74
+ public static function parseKey(array $jwk)
75
  {
76
  if (empty($jwk)) {
77
  throw new InvalidArgumentException('JWK must not be empty');
78
  }
 
79
  if (!isset($jwk['kty'])) {
80
  throw new UnexpectedValueException('JWK must contain a "kty" parameter');
81
  }
82
 
 
 
 
 
 
 
 
 
 
 
 
83
  switch ($jwk['kty']) {
84
  case 'RSA':
85
  if (!empty($jwk['d'])) {
96
  'OpenSSL error: ' . \openssl_error_string()
97
  );
98
  }
99
+ return $publicKey;
100
  default:
101
  // Currently only RSA is supported
102
  break;
103
  }
 
 
104
  }
105
 
106
  /**
113
  *
114
  * @uses encodeLength
115
  */
116
+ private static function createPemFromModulusAndExponent($n, $e)
117
+ {
118
+ $modulus = JWT::urlsafeB64Decode($n);
119
+ $publicExponent = JWT::urlsafeB64Decode($e);
 
 
120
 
121
+ $components = array(
122
+ 'modulus' => \pack('Ca*a*', 2, self::encodeLength(\strlen($modulus)), $modulus),
123
+ 'publicExponent' => \pack('Ca*a*', 2, self::encodeLength(\strlen($publicExponent)), $publicExponent)
124
+ );
125
 
126
  $rsaPublicKey = \pack(
127
  'Ca*a*a*',
128
  48,
129
+ self::encodeLength(\strlen($components['modulus']) + \strlen($components['publicExponent'])),
130
+ $components['modulus'],
131
+ $components['publicExponent']
132
  );
133
 
134
  // sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption.
159
  * @param int $length
160
  * @return string
161
  */
162
+ private static function encodeLength($length)
163
  {
164
  if ($length <= 0x7F) {
165
  return \chr($length);
vendor/firebase/php-jwt/src/JWT.php CHANGED
@@ -3,14 +3,12 @@
3
  namespace Firebase\JWT;
4
 
5
  use ArrayAccess;
6
- use DateTime;
7
  use DomainException;
8
  use Exception;
9
  use InvalidArgumentException;
10
  use OpenSSLAsymmetricKey;
11
- use OpenSSLCertificate;
12
- use stdClass;
13
  use UnexpectedValueException;
 
14
 
15
  /**
16
  * JSON Web Token implementation, based on this spec:
@@ -27,57 +25,52 @@ use UnexpectedValueException;
27
  */
28
  class JWT
29
  {
30
- private const ASN1_INTEGER = 0x02;
31
- private const ASN1_SEQUENCE = 0x10;
32
- private const ASN1_BIT_STRING = 0x03;
33
 
34
  /**
35
  * When checking nbf, iat or expiration times,
36
  * we want to provide some extra leeway time to
37
  * account for clock skew.
38
- *
39
- * @var int
40
  */
41
  public static $leeway = 0;
42
 
43
  /**
44
  * Allow the current timestamp to be specified.
45
  * Useful for fixing a value within unit testing.
46
- * Will default to PHP time() value if null.
47
  *
48
- * @var ?int
49
  */
50
  public static $timestamp = null;
51
 
52
- /**
53
- * @var array<string, string[]>
54
- */
55
- public static $supported_algs = [
56
- 'ES384' => ['openssl', 'SHA384'],
57
- 'ES256' => ['openssl', 'SHA256'],
58
- 'HS256' => ['hash_hmac', 'SHA256'],
59
- 'HS384' => ['hash_hmac', 'SHA384'],
60
- 'HS512' => ['hash_hmac', 'SHA512'],
61
- 'RS256' => ['openssl', 'SHA256'],
62
- 'RS384' => ['openssl', 'SHA384'],
63
- 'RS512' => ['openssl', 'SHA512'],
64
- 'EdDSA' => ['sodium_crypto', 'EdDSA'],
65
- ];
66
 
67
  /**
68
  * Decodes a JWT string into a PHP object.
69
  *
70
- * @param string $jwt The JWT
71
- * @param Key|array<string,Key> $keyOrKeyArray The Key or associative array of key IDs (kid) to Key objects.
72
- * If the algorithm used is asymmetric, this is the public key
73
- * Each Key object contains an algorithm and matching key.
74
- * Supported algorithms are 'ES384','ES256', 'HS256', 'HS384',
75
- * 'HS512', 'RS256', 'RS384', and 'RS512'
 
 
76
  *
77
- * @return stdClass The JWT's payload as a PHP object
78
  *
79
- * @throws InvalidArgumentException Provided key/key-array was empty
80
- * @throws DomainException Provided JWT is malformed
81
  * @throws UnexpectedValueException Provided JWT was invalid
82
  * @throws SignatureInvalidException Provided JWT was invalid because the signature verification failed
83
  * @throws BeforeValidException Provided JWT is trying to be used before it's eligible as defined by 'nbf'
@@ -87,11 +80,8 @@ class JWT
87
  * @uses jsonDecode
88
  * @uses urlsafeB64Decode
89
  */
90
- public static function decode(
91
- string $jwt,
92
- $keyOrKeyArray
93
- ): stdClass {
94
- // Validate JWT
95
  $timestamp = \is_null(static::$timestamp) ? \time() : static::$timestamp;
96
 
97
  if (empty($keyOrKeyArray)) {
@@ -102,22 +92,15 @@ class JWT
102
  throw new UnexpectedValueException('Wrong number of segments');
103
  }
104
  list($headb64, $bodyb64, $cryptob64) = $tks;
105
- $headerRaw = static::urlsafeB64Decode($headb64);
106
- if (null === ($header = static::jsonDecode($headerRaw))) {
107
  throw new UnexpectedValueException('Invalid header encoding');
108
  }
109
- $payloadRaw = static::urlsafeB64Decode($bodyb64);
110
- if (null === ($payload = static::jsonDecode($payloadRaw))) {
111
  throw new UnexpectedValueException('Invalid claims encoding');
112
  }
113
- if (\is_array($payload)) {
114
- // prevent PHP Fatal Error in edge-cases when payload is empty array
115
- $payload = (object) $payload;
116
- }
117
- if (!$payload instanceof stdClass) {
118
- throw new UnexpectedValueException('Payload must be a JSON object');
119
  }
120
- $sig = static::urlsafeB64Decode($cryptob64);
121
  if (empty($header->alg)) {
122
  throw new UnexpectedValueException('Empty algorithm');
123
  }
@@ -125,18 +108,31 @@ class JWT
125
  throw new UnexpectedValueException('Algorithm not supported');
126
  }
127
 
128
- $key = self::getKey($keyOrKeyArray, property_exists($header, 'kid') ? $header->kid : null);
 
 
 
129
 
130
- // Check the algorithm
131
- if (!self::constantTimeEquals($key->getAlgorithm(), $header->alg)) {
132
- // See issue #351
133
- throw new UnexpectedValueException('Incorrect key for this algorithm');
 
 
 
 
 
 
 
 
 
134
  }
135
  if ($header->alg === 'ES256' || $header->alg === 'ES384') {
136
  // OpenSSL expects an ASN.1 DER sequence for ES256/ES384 signatures
137
  $sig = self::signatureToDER($sig);
138
  }
139
- if (!self::verify("$headb64.$bodyb64", $sig, $key->getKeyMaterial(), $header->alg)) {
 
140
  throw new SignatureInvalidException('Signature verification failed');
141
  }
142
 
@@ -168,35 +164,32 @@ class JWT
168
  /**
169
  * Converts and signs a PHP object or array into a JWT string.
170
  *
171
- * @param array<mixed> $payload PHP array
172
- * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key.
173
- * @param string $alg Supported algorithms are 'ES384','ES256', 'HS256', 'HS384',
174
- * 'HS512', 'RS256', 'RS384', and 'RS512'
175
- * @param string $keyId
176
- * @param array<string, string> $head An array with header elements to attach
 
 
177
  *
178
  * @return string A signed JWT
179
  *
180
  * @uses jsonEncode
181
  * @uses urlsafeB64Encode
182
  */
183
- public static function encode(
184
- array $payload,
185
- $key,
186
- string $alg,
187
- string $keyId = null,
188
- array $head = null
189
- ): string {
190
- $header = ['typ' => 'JWT', 'alg' => $alg];
191
  if ($keyId !== null) {
192
  $header['kid'] = $keyId;
193
  }
194
  if (isset($head) && \is_array($head)) {
195
  $header = \array_merge($head, $header);
196
  }
197
- $segments = [];
198
- $segments[] = static::urlsafeB64Encode((string) static::jsonEncode($header));
199
- $segments[] = static::urlsafeB64Encode((string) static::jsonEncode($payload));
200
  $signing_input = \implode('.', $segments);
201
 
202
  $signature = static::sign($signing_input, $key, $alg);
@@ -208,35 +201,30 @@ class JWT
208
  /**
209
  * Sign a string with a given key and algorithm.
210
  *
211
- * @param string $msg The message to sign
212
- * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key.
213
- * @param string $alg Supported algorithms are 'ES384','ES256', 'HS256', 'HS384',
214
- * 'HS512', 'RS256', 'RS384', and 'RS512'
 
215
  *
216
  * @return string An encrypted message
217
  *
218
  * @throws DomainException Unsupported algorithm or bad key was specified
219
  */
220
- public static function sign(
221
- string $msg,
222
- $key,
223
- string $alg
224
- ): string {
225
  if (empty(static::$supported_algs[$alg])) {
226
  throw new DomainException('Algorithm not supported');
227
  }
228
  list($function, $algorithm) = static::$supported_algs[$alg];
229
  switch ($function) {
230
  case 'hash_hmac':
231
- if (!\is_string($key)) {
232
- throw new InvalidArgumentException('key must be a string when using hmac');
233
- }
234
  return \hash_hmac($algorithm, $msg, $key, true);
235
  case 'openssl':
236
  $signature = '';
237
- $success = \openssl_sign($msg, $signature, $key, $algorithm); // @phpstan-ignore-line
238
  if (!$success) {
239
- throw new DomainException('OpenSSL unable to sign data');
240
  }
241
  if ($alg === 'ES256') {
242
  $signature = self::signatureFromDER($signature, 256);
@@ -245,44 +233,35 @@ class JWT
245
  }
246
  return $signature;
247
  case 'sodium_crypto':
248
- if (!\function_exists('sodium_crypto_sign_detached')) {
249
  throw new DomainException('libsodium is not available');
250
  }
251
- if (!\is_string($key)) {
252
- throw new InvalidArgumentException('key must be a string when using EdDSA');
253
- }
254
  try {
255
  // The last non-empty line is used as the key.
256
  $lines = array_filter(explode("\n", $key));
257
- $key = base64_decode((string) end($lines));
258
  return sodium_crypto_sign_detached($msg, $key);
259
  } catch (Exception $e) {
260
  throw new DomainException($e->getMessage(), 0, $e);
261
  }
262
  }
263
-
264
- throw new DomainException('Algorithm not supported');
265
  }
266
 
267
  /**
268
  * Verify a signature with the message, key and method. Not all methods
269
  * are symmetric, so we must have a separate verify and sign method.
270
  *
271
- * @param string $msg The original message (header and body)
272
- * @param string $signature The original signature
273
- * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial For HS*, a string key works. for RS*, must be an instance of OpenSSLAsymmetricKey
274
- * @param string $alg The algorithm
275
  *
276
  * @return bool
277
  *
278
  * @throws DomainException Invalid Algorithm, bad key, or OpenSSL failure
279
  */
280
- private static function verify(
281
- string $msg,
282
- string $signature,
283
- $keyMaterial,
284
- string $alg
285
- ): bool {
286
  if (empty(static::$supported_algs[$alg])) {
287
  throw new DomainException('Algorithm not supported');
288
  }
@@ -290,7 +269,7 @@ class JWT
290
  list($function, $algorithm) = static::$supported_algs[$alg];
291
  switch ($function) {
292
  case 'openssl':
293
- $success = \openssl_verify($msg, $signature, $keyMaterial, $algorithm); // @phpstan-ignore-line
294
  if ($success === 1) {
295
  return true;
296
  } elseif ($success === 0) {
@@ -301,27 +280,21 @@ class JWT
301
  'OpenSSL error: ' . \openssl_error_string()
302
  );
303
  case 'sodium_crypto':
304
- if (!\function_exists('sodium_crypto_sign_verify_detached')) {
305
  throw new DomainException('libsodium is not available');
306
  }
307
- if (!\is_string($keyMaterial)) {
308
- throw new InvalidArgumentException('key must be a string when using EdDSA');
309
- }
310
  try {
311
  // The last non-empty line is used as the key.
312
- $lines = array_filter(explode("\n", $keyMaterial));
313
- $key = base64_decode((string) end($lines));
314
  return sodium_crypto_sign_verify_detached($signature, $msg, $key);
315
  } catch (Exception $e) {
316
  throw new DomainException($e->getMessage(), 0, $e);
317
  }
318
  case 'hash_hmac':
319
  default:
320
- if (!\is_string($keyMaterial)) {
321
- throw new InvalidArgumentException('key must be a string when using hmac');
322
- }
323
- $hash = \hash_hmac($algorithm, $msg, $keyMaterial, true);
324
- return self::constantTimeEquals($hash, $signature);
325
  }
326
  }
327
 
@@ -330,16 +303,30 @@ class JWT
330
  *
331
  * @param string $input JSON string
332
  *
333
- * @return mixed The decoded JSON string
334
  *
335
  * @throws DomainException Provided string was invalid JSON
336
  */
337
- public static function jsonDecode(string $input)
338
  {
339
- $obj = \json_decode($input, false, 512, JSON_BIGINT_AS_STRING);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340
 
341
  if ($errno = \json_last_error()) {
342
- self::handleJsonError($errno);
343
  } elseif ($obj === null && $input !== 'null') {
344
  throw new DomainException('Null result with non-null input');
345
  }
@@ -347,30 +334,22 @@ class JWT
347
  }
348
 
349
  /**
350
- * Encode a PHP array into a JSON string.
351
  *
352
- * @param array<mixed> $input A PHP array
353
  *
354
- * @return string JSON representation of the PHP array
355
  *
356
  * @throws DomainException Provided object could not be encoded to valid JSON
357
  */
358
- public static function jsonEncode(array $input): string
359
  {
360
- if (PHP_VERSION_ID >= 50400) {
361
- $json = \json_encode($input, \JSON_UNESCAPED_SLASHES);
362
- } else {
363
- // PHP 5.3 only
364
- $json = \json_encode($input);
365
- }
366
  if ($errno = \json_last_error()) {
367
- self::handleJsonError($errno);
368
  } elseif ($json === 'null' && $input !== null) {
369
  throw new DomainException('Null result with non-null input');
370
  }
371
- if ($json === false) {
372
- throw new DomainException('Provided object could not be encoded to valid JSON');
373
- }
374
  return $json;
375
  }
376
 
@@ -380,10 +359,8 @@ class JWT
380
  * @param string $input A Base64 encoded string
381
  *
382
  * @return string A decoded string
383
- *
384
- * @throws InvalidArgumentException invalid base64 characters
385
  */
386
- public static function urlsafeB64Decode(string $input): string
387
  {
388
  $remainder = \strlen($input) % 4;
389
  if ($remainder) {
@@ -400,7 +377,7 @@ class JWT
400
  *
401
  * @return string The base64 encode of what you passed in
402
  */
403
- public static function urlsafeB64Encode(string $input): string
404
  {
405
  return \str_replace('=', '', \strtr(\base64_encode($input), '+/', '-_'));
406
  }
@@ -409,53 +386,67 @@ class JWT
409
  /**
410
  * Determine if an algorithm has been provided for each Key
411
  *
412
- * @param Key|ArrayAccess<string,Key>|array<string,Key> $keyOrKeyArray
413
- * @param string|null $kid
414
  *
415
  * @throws UnexpectedValueException
416
  *
417
- * @return Key
418
  */
419
- private static function getKey(
420
- $keyOrKeyArray,
421
- ?string $kid
422
- ): Key {
423
- if ($keyOrKeyArray instanceof Key) {
424
- return $keyOrKeyArray;
 
 
425
  }
426
 
427
- if ($keyOrKeyArray instanceof CachedKeySet) {
428
- // Skip "isset" check, as this will automatically refresh if not set
429
- return $keyOrKeyArray[$kid];
430
  }
431
 
432
- if (empty($kid)) {
433
- throw new UnexpectedValueException('"kid" empty, unable to lookup correct key');
434
- }
435
- if (!isset($keyOrKeyArray[$kid])) {
436
- throw new UnexpectedValueException('"kid" invalid, unable to lookup correct key');
 
 
 
 
 
 
 
 
 
 
437
  }
438
 
439
- return $keyOrKeyArray[$kid];
 
 
 
440
  }
441
 
442
  /**
443
- * @param string $left The string of known length to compare against
444
- * @param string $right The user-supplied string
445
  * @return bool
446
  */
447
- public static function constantTimeEquals(string $left, string $right): bool
448
  {
449
  if (\function_exists('hash_equals')) {
450
  return \hash_equals($left, $right);
451
  }
452
- $len = \min(self::safeStrlen($left), self::safeStrlen($right));
453
 
454
  $status = 0;
455
  for ($i = 0; $i < $len; $i++) {
456
  $status |= (\ord($left[$i]) ^ \ord($right[$i]));
457
  }
458
- $status |= (self::safeStrlen($left) ^ self::safeStrlen($right));
459
 
460
  return ($status === 0);
461
  }
@@ -465,19 +456,17 @@ class JWT
465
  *
466
  * @param int $errno An error number from json_last_error()
467
  *
468
- * @throws DomainException
469
- *
470
  * @return void
471
  */
472
- private static function handleJsonError(int $errno): void
473
  {
474
- $messages = [
475
  JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
476
  JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON',
477
  JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
478
  JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON',
479
  JSON_ERROR_UTF8 => 'Malformed UTF-8 characters' //PHP >= 5.3.3
480
- ];
481
  throw new DomainException(
482
  isset($messages[$errno])
483
  ? $messages[$errno]
@@ -492,7 +481,7 @@ class JWT
492
  *
493
  * @return int
494
  */
495
- private static function safeStrlen(string $str): int
496
  {
497
  if (\function_exists('mb_strlen')) {
498
  return \mb_strlen($str, '8bit');
@@ -506,11 +495,10 @@ class JWT
506
  * @param string $sig The ECDSA signature to convert
507
  * @return string The encoded DER object
508
  */
509
- private static function signatureToDER(string $sig): string
510
  {
511
  // Separate the signature into r-value and s-value
512
- $length = max(1, (int) (\strlen($sig) / 2));
513
- list($r, $s) = \str_split($sig, $length > 0 ? $length : 1);
514
 
515
  // Trim leading zeros
516
  $r = \ltrim($r, "\x00");
@@ -537,10 +525,9 @@ class JWT
537
  *
538
  * @param int $type DER tag
539
  * @param string $value the value to encode
540
- *
541
  * @return string the encoded object
542
  */
543
- private static function encodeDER(int $type, string $value): string
544
  {
545
  $tag_header = 0;
546
  if ($type === self::ASN1_SEQUENCE) {
@@ -561,10 +548,9 @@ class JWT
561
  *
562
  * @param string $der binary signature in DER format
563
  * @param int $keySize the number of bits in the key
564
- *
565
  * @return string the signature
566
  */
567
- private static function signatureFromDER(string $der, int $keySize): string
568
  {
569
  // OpenSSL returns the ECDSA signatures as a binary ASN.1 DER SEQUENCE
570
  list($offset, $_) = self::readDER($der);
@@ -589,10 +575,9 @@ class JWT
589
  * @param string $der the binary data in DER format
590
  * @param int $offset the offset of the data stream containing the object
591
  * to decode
592
- *
593
- * @return array{int, string|null} the new offset and the decoded object
594
  */
595
- private static function readDER(string $der, int $offset = 0): array
596
  {
597
  $pos = $offset;
598
  $size = \strlen($der);
@@ -621,6 +606,6 @@ class JWT
621
  $data = null;
622
  }
623
 
624
- return [$pos, $data];
625
  }
626
  }
3
  namespace Firebase\JWT;
4
 
5
  use ArrayAccess;
 
6
  use DomainException;
7
  use Exception;
8
  use InvalidArgumentException;
9
  use OpenSSLAsymmetricKey;
 
 
10
  use UnexpectedValueException;
11
+ use DateTime;
12
 
13
  /**
14
  * JSON Web Token implementation, based on this spec:
25
  */
26
  class JWT
27
  {
28
+ const ASN1_INTEGER = 0x02;
29
+ const ASN1_SEQUENCE = 0x10;
30
+ const ASN1_BIT_STRING = 0x03;
31
 
32
  /**
33
  * When checking nbf, iat or expiration times,
34
  * we want to provide some extra leeway time to
35
  * account for clock skew.
 
 
36
  */
37
  public static $leeway = 0;
38
 
39
  /**
40
  * Allow the current timestamp to be specified.
41
  * Useful for fixing a value within unit testing.
 
42
  *
43
+ * Will default to PHP time() value if null.
44
  */
45
  public static $timestamp = null;
46
 
47
+ public static $supported_algs = array(
48
+ 'ES384' => array('openssl', 'SHA384'),
49
+ 'ES256' => array('openssl', 'SHA256'),
50
+ 'HS256' => array('hash_hmac', 'SHA256'),
51
+ 'HS384' => array('hash_hmac', 'SHA384'),
52
+ 'HS512' => array('hash_hmac', 'SHA512'),
53
+ 'RS256' => array('openssl', 'SHA256'),
54
+ 'RS384' => array('openssl', 'SHA384'),
55
+ 'RS512' => array('openssl', 'SHA512'),
56
+ 'EdDSA' => array('sodium_crypto', 'EdDSA'),
57
+ );
 
 
 
58
 
59
  /**
60
  * Decodes a JWT string into a PHP object.
61
  *
62
+ * @param string $jwt The JWT
63
+ * @param Key|array<Key>|mixed $keyOrKeyArray The Key or array of Key objects.
64
+ * If the algorithm used is asymmetric, this is the public key
65
+ * Each Key object contains an algorithm and matching key.
66
+ * Supported algorithms are 'ES384','ES256', 'HS256', 'HS384',
67
+ * 'HS512', 'RS256', 'RS384', and 'RS512'
68
+ * @param array $allowed_algs [DEPRECATED] List of supported verification algorithms. Only
69
+ * should be used for backwards compatibility.
70
  *
71
+ * @return object The JWT's payload as a PHP object
72
  *
73
+ * @throws InvalidArgumentException Provided JWT was empty
 
74
  * @throws UnexpectedValueException Provided JWT was invalid
75
  * @throws SignatureInvalidException Provided JWT was invalid because the signature verification failed
76
  * @throws BeforeValidException Provided JWT is trying to be used before it's eligible as defined by 'nbf'
80
  * @uses jsonDecode
81
  * @uses urlsafeB64Decode
82
  */
83
+ public static function decode($jwt, $keyOrKeyArray, array $allowed_algs = array())
84
+ {
 
 
 
85
  $timestamp = \is_null(static::$timestamp) ? \time() : static::$timestamp;
86
 
87
  if (empty($keyOrKeyArray)) {
92
  throw new UnexpectedValueException('Wrong number of segments');
93
  }
94
  list($headb64, $bodyb64, $cryptob64) = $tks;
95
+ if (null === ($header = static::jsonDecode(static::urlsafeB64Decode($headb64)))) {
 
96
  throw new UnexpectedValueException('Invalid header encoding');
97
  }
98
+ if (null === $payload = static::jsonDecode(static::urlsafeB64Decode($bodyb64))) {
 
99
  throw new UnexpectedValueException('Invalid claims encoding');
100
  }
101
+ if (false === ($sig = static::urlsafeB64Decode($cryptob64))) {
102
+ throw new UnexpectedValueException('Invalid signature encoding');
 
 
 
 
103
  }
 
104
  if (empty($header->alg)) {
105
  throw new UnexpectedValueException('Empty algorithm');
106
  }
108
  throw new UnexpectedValueException('Algorithm not supported');
109
  }
110
 
111
+ list($keyMaterial, $algorithm) = self::getKeyMaterialAndAlgorithm(
112
+ $keyOrKeyArray,
113
+ empty($header->kid) ? null : $header->kid
114
+ );
115
 
116
+ if (empty($algorithm)) {
117
+ // Use deprecated "allowed_algs" to determine if the algorithm is supported.
118
+ // This opens up the possibility of an attack in some implementations.
119
+ // @see https://github.com/firebase/php-jwt/issues/351
120
+ if (!\in_array($header->alg, $allowed_algs)) {
121
+ throw new UnexpectedValueException('Algorithm not allowed');
122
+ }
123
+ } else {
124
+ // Check the algorithm
125
+ if (!self::constantTimeEquals($algorithm, $header->alg)) {
126
+ // See issue #351
127
+ throw new UnexpectedValueException('Incorrect key for this algorithm');
128
+ }
129
  }
130
  if ($header->alg === 'ES256' || $header->alg === 'ES384') {
131
  // OpenSSL expects an ASN.1 DER sequence for ES256/ES384 signatures
132
  $sig = self::signatureToDER($sig);
133
  }
134
+
135
+ if (!static::verify("$headb64.$bodyb64", $sig, $keyMaterial, $header->alg)) {
136
  throw new SignatureInvalidException('Signature verification failed');
137
  }
138
 
164
  /**
165
  * Converts and signs a PHP object or array into a JWT string.
166
  *
167
+ * @param object|array $payload PHP object or array
168
+ * @param string|resource $key The secret key.
169
+ * If the algorithm used is asymmetric, this is the private key
170
+ * @param string $alg The signing algorithm.
171
+ * Supported algorithms are 'ES384','ES256', 'HS256', 'HS384',
172
+ * 'HS512', 'RS256', 'RS384', and 'RS512'
173
+ * @param mixed $keyId
174
+ * @param array $head An array with header elements to attach
175
  *
176
  * @return string A signed JWT
177
  *
178
  * @uses jsonEncode
179
  * @uses urlsafeB64Encode
180
  */
181
+ public static function encode($payload, $key, $alg = 'HS256', $keyId = null, $head = null)
182
+ {
183
+ $header = array('typ' => 'JWT', 'alg' => $alg);
 
 
 
 
 
184
  if ($keyId !== null) {
185
  $header['kid'] = $keyId;
186
  }
187
  if (isset($head) && \is_array($head)) {
188
  $header = \array_merge($head, $header);
189
  }
190
+ $segments = array();
191
+ $segments[] = static::urlsafeB64Encode(static::jsonEncode($header));
192
+ $segments[] = static::urlsafeB64Encode(static::jsonEncode($payload));
193
  $signing_input = \implode('.', $segments);
194
 
195
  $signature = static::sign($signing_input, $key, $alg);
201
  /**
202
  * Sign a string with a given key and algorithm.
203
  *
204
+ * @param string $msg The message to sign
205
+ * @param string|resource $key The secret key
206
+ * @param string $alg The signing algorithm.
207
+ * Supported algorithms are 'ES384','ES256', 'HS256', 'HS384',
208
+ * 'HS512', 'RS256', 'RS384', and 'RS512'
209
  *
210
  * @return string An encrypted message
211
  *
212
  * @throws DomainException Unsupported algorithm or bad key was specified
213
  */
214
+ public static function sign($msg, $key, $alg = 'HS256')
215
+ {
 
 
 
216
  if (empty(static::$supported_algs[$alg])) {
217
  throw new DomainException('Algorithm not supported');
218
  }
219
  list($function, $algorithm) = static::$supported_algs[$alg];
220
  switch ($function) {
221
  case 'hash_hmac':