@automattic/newspack-blocks 4.28.1-hotfix-blocks-input-validation.2 → 4.28.1-hotfix-blocks-input-validation.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md CHANGED
@@ -207,7 +207,7 @@ REST controllers are instantiated via wrapper functions hooked to `rest_api_init
207
207
  - **Functions**: `newspack_blocks_*` prefix (e.g., `newspack_blocks_render_block_homepage_articles`)
208
208
  - **Classes**: `Newspack_Blocks*` or `WP_REST_Newspack_*` for REST controllers
209
209
  - **Constants**: `NEWSPACK_BLOCKS__*` (double underscore)
210
- - **Hooks**: `newspack_blocks_*` prefix; modal-specific use `newspack_modal_checkout_*`
210
+ - **Hooks**: `newspack_blocks_*` prefix; modal-specific use `newspack_blocks_modal_checkout_*`
211
211
  - **Text domain**: `newspack-blocks`
212
212
  - **Block names**: Short slugs in `block.json`, namespaced as `newspack-blocks/<slug>` in PHP/JS
213
213
 
@@ -268,7 +268,7 @@ Partial adoption. Some blocks use `.ts`/`.tsx` (homepage-articles `edit.tsx`, do
268
268
  The plugin exposes many hooks. Rather than listing them all here (they change over time), use `grep -r 'apply_filters\|do_action' src/ includes/` to find current hooks. The key hook prefixes are:
269
269
 
270
270
  - **`newspack_blocks_*`**: General block hooks (query building, deduplication, registration, author data)
271
- - **`newspack_modal_checkout_*`**: Modal checkout specific hooks (labels, gateways, billing fields, HTML output)
271
+ - **`newspack_blocks_modal_checkout_*`**: Modal checkout specific hooks (labels, gateways, billing fields, HTML output)
272
272
 
273
273
  ## CI/CD
274
274
 
package/CHANGELOG.md CHANGED
@@ -1,9 +1,11 @@
1
- ## @automattic/newspack-blocks [4.28.1-hotfix-blocks-input-validation.2](https://github.com/Automattic/newspack-workspace/compare/newspack-blocks@4.28.1-hotfix-blocks-input-validation.1...newspack-blocks@4.28.1-hotfix-blocks-input-validation.2) (2026-07-31)
1
+ ## @automattic/newspack-blocks [4.28.1-hotfix-blocks-input-validation.4](https://github.com/Automattic/newspack-workspace/compare/newspack-blocks@4.28.1-hotfix-blocks-input-validation.3...newspack-blocks@4.28.1-hotfix-blocks-input-validation.4) (2026-08-06)
2
2
 
3
3
 
4
4
  ### Bug Fixes
5
5
 
6
- * **blocks:** close after-success dead ends and tighten write checks ([12e6bd8](https://github.com/Automattic/newspack-workspace/commit/12e6bd898d28eaf4fb6a59633f99b297febc308f))
6
+ * **blocks:** bind post-checkout destination tokens to published posts ([f4bf13e](https://github.com/Automattic/newspack-workspace/commit/f4bf13e95da3dbe3fc9430c5f3aa06758c81ba34))
7
+ * **blocks:** keep protocol-relative post-checkout destinations intact ([2fa64cc](https://github.com/Automattic/newspack-workspace/commit/2fa64cc9f09a9f2a5bd48de28aba9ed298be4572))
8
+ * **blocks:** sign publisher-configured post-checkout destinations ([3ec364b](https://github.com/Automattic/newspack-workspace/commit/3ec364b021b321e7732f564c7a18f706985a8544))
7
9
 
8
10
  # @automattic/newspack-blocks [4.28.0](https://github.com/Automattic/newspack-workspace/compare/newspack-blocks@4.27.1...newspack-blocks@4.28.0) (2026-07-20)
9
11
 
@@ -1 +1 @@
1
- <?php return array('dependencies' => array(), 'version' => 'b79d97b30970c302d04a');
1
+ <?php return array('dependencies' => array(), 'version' => 'f9760843d53d18537bf6');
package/dist/modal.js CHANGED
@@ -1 +1 @@
1
- (()=>{"use strict";function e(e,t=!1){const n=e.querySelectorAll('button, [href], input:not([type="hidden"]), select, textarea, [tabindex]:not([tabindex="-1"])');if(0===n.length)return!1;const o=n?.[0];let c;o.focus(),t?(document.addEventListener("keydown",function(e){if(("Tab"===e.key||9===e.keyCode)&&e.shiftKey&&document.activeElement===o){const n=t.contentWindow.document,o=n.getElementById("checkout-after-success");c=null!==o?o:n.getElementById("checkout_cancel"),c.focus(),e.preventDefault()}}),document.getElementById("newspack-a11y-last-element").addEventListener("focus",()=>{o.focus()})):(c=n[n.length-1],document.addEventListener("keydown",function(e){("Tab"===e.key||9===e.keyCode)&&(e.shiftKey?document.activeElement===o&&(c.focus(),e.preventDefault()):document.activeElement===c&&(o.focus(),e.preventDefault()))}))}const t=(e,t={})=>({...t,action:e}),n=["action","action_type","amount","currency","product_id","product_type","variation_id","variation_ids","is_variable","is_grouped","child_ids","price_summary","newspack_popup_id","prompt_title","gate_post_id","recurrence","referrer"],o=(e,t="np_modal_checkout_interaction")=>{if("function"==typeof window.gtag&&e){const o={};for(const t of n)e[t]&&("boolean"==typeof e[t]?e[t]=e[t]?"yes":"no":"true"===e[t]?e[t]="yes":"false"===e[t]&&(e[t]="no"),o[t]=e[t].toString());window.gtag("event",t,o)}},c=e=>{if("function"!=typeof window.gtag)return;let n="opened";const{amount:c="",is_variable:a="",is_grouped:r="",price:i="",variation_id:s=""}=e,l={...e};(c||i)&&(l.amount=c||i),a&&!s&&(n="opened_variations"),r&&(n="opened_grouped");const u=t(n,l);o(u)};function a(e,t=null){const n=document.createElement("input");return n.type="hidden",n.name=e,t&&(n.value=t),n}function r(e){e.requestSubmit(e.querySelector('button[type="submit"]'))}function i(e){const t="string"==typeof e?document.getElementById(e):e;if(!t)return console.warn("No container found for checkout data"),{};let n={};if("FORM"===t.tagName){const e=new FormData(t);n=Object.fromEntries(e)}const o=t.dataset.checkout;if(!o)return console.warn("No checkout data found"),n;try{n={...n,...JSON.parse(o)}}catch(e){console.warn("Error parsing checkout data")}const c=new URL(t.ownerDocument.defaultView.location.href);return c.searchParams.get("action_type")&&(n.action_type=c.searchParams.get("action_type")),n}const s=e=>{if("function"!=typeof window.gtag)return;e=e||i("newspack_modal_checkout");const n=t("dismissed",e);o(n)};function l(e){const t=e&&e.dataset?e.dataset.checkout:null;if(!t)return null;try{return JSON.parse(t)}catch(e){return null}}function u(e,t,n=null){const o=e.querySelectorAll(".wp-block-newspack-blocks-checkout-button"),c=null!=n&&""!==String(n);let a=null;return o.forEach(e=>{if(a)return;const o=e.querySelector("form"),r=l(o);r&&String(r.product_id)===String(t)&&(c&&String(r.variation_id)!==String(n)||(a=o))}),a}const d=["after_success_behavior","after_success_url","after_success_button_label","gate_post_id","newspack_popup_id","prompt_title"];const p={gate:"gate_post_id",prompt:"newspack_popup_id"};const m=newspackBlocksModal.newspack_class_prefix,_="newspack_modal_checkout_iframe",h="newspack_modal_checkout_container",y=`${m}__modal`,w="newspack-blocks__modal-variation",f=`${m}__processing-payment-text`,k=newspackBlocksModal.processing_payment_messages;let v=!1,g=newspackBlocksModal.labels.checkout_modal_title,b=null;const S=e=>{e.overlayId&&window.newspackReaderActivation?.overlays&&window.newspackReaderActivation?.overlays.remove(e.overlayId),e.setAttribute("data-state","closed"),document.body.style.overflow="auto"};window.onpageshow=e=>{e.persisted&&(document.querySelectorAll(".modal-processing").forEach(e=>e.classList.remove("modal-processing")),document.querySelectorAll(".non-modal-checkout-loading").forEach(e=>e.classList.remove("non-modal-checkout-loading")),document.querySelectorAll(`.${y}-container`).forEach(e=>S(e)))};const E=new CustomEvent("checkout-closed");var q;window.newspackRAS=window.newspackRAS||[],q=()=>{const t=document.querySelector("#newspack_modal_checkout");if(!t)return;const n=t.querySelector(`.${y}__content`),o=a("modal_checkout","1"),q=n.querySelector(`.${m}__spinner`);let A=document.querySelector(".newspack-reader__account-link")?.[0];const L="600px",$=document.createElement("iframe");$.name=_,$.style.height=L,$.style.visibility="hidden";const R=e=>{P.observe(e),"none"!==q.style.display&&(q.style.display="none"),"visible"!==$.style.visibility&&($.style.visibility="visible"),$._ready=!0};!function(e,t,n){e._ready=!1,e._readyTimer&&clearTimeout(e._readyTimer);let o=!1,c="";function a(){o||(o=!0,clearTimeout(e._readyTimer),t.call(this))}function r(){"complete"===this.readyState&&a.call(this)}function i(){e._ready=!1,n&&n(),e._readyTimer&&clearTimeout(e._readyTimer);const t=e.contentDocument||e.contentWindow?.document;t&&(t.removeEventListener("DOMContentLoaded",a),t.removeEventListener("readystatechange",r))}function s(){if(e._ready)return void i();const t=e.contentDocument||e.contentWindow?.document;t&&0!==t.URL.indexOf("about:")?"complete"===t?.readyState?a.call(t):(t.addEventListener("DOMContentLoaded",a),t.addEventListener("readystatechange",r)):e._readyTimer=setTimeout(s,10)}e._observer||(e._observer=new MutationObserver(e=>{e.forEach(e=>{"attributes"===e.type&&"src"===e.attributeName&&(o=!1,i(),s())})}),e._observer.observe(e,{attributes:!0})),e._locationObserver||(e._locationObserver=setInterval(function(){const t=e.contentDocument||e.contentWindow?.document;t&&t.URL!==c&&(c=t.URL,o=!1,i(),s())},50)),s()}($,function(){const n=$.contentWindow?.location;if(window.newspackReaderActivation&&n?.href?.includes("order-received")){const e=window.newspackReaderActivation,t=new Proxy(new URLSearchParams(n.search),{get:(e,t)=>e.get(t)});t.email&&(e.setReaderEmail(t.email),e.setAuthenticated(!0))}const o=$?.contentDocument?.querySelector(`#${h}`);if(!o)return;const c=o.querySelector("#modal-checkout-product-details"),a=i(c),r=document.createElement("p");r.classList.add(f);let s=[];const l=()=>{s.forEach(e=>clearTimeout(e)),s=[]},u=()=>{q.style.display="none",l(),q.querySelectorAll(`.${f}`).forEach(e=>e.remove())};!function(e,t){e.checkoutCancel?t():e.addEventListener("checkout-cancel",t)}(o,()=>{D()}),function(e,t){e.checkoutPlaceOrderStart?t():e.addEventListener("checkout-place-order-start",t)}(o,e=>{q.querySelectorAll(`.${f}`).forEach(e=>e.remove()),q.style.display="flex",l(),r.textContent=k[0]?.text??"",k.slice(1).forEach(({text:t,delay:n})=>{const o=setTimeout(()=>{e.target.dispatchEvent(new CustomEvent("checkout-place-order-processing")),r.textContent=t},n);s.push(o)}),q.appendChild(r)}),function(e,t){e.checkoutPlaceOrderError?t():e.addEventListener("checkout-place-order-error",t)}(o,u),function(e,t){e.checkoutReady?t():e.addEventListener("checkout-ready",t)}(o,()=>{const e=c?.querySelector("strong");if(e&&(e.textContent=a.price_summary),t.initialErrors){const e=document.createElement("div");e.classList.add("woocommerce-error"),e.textContent=t.initialErrors,o.prepend(e),delete t.initialErrors}I(),N(g),$.contentWindow?.newspackBlocksModalCheckout?.checkout_nonce&&(t.checkout_nonce=$.contentWindow.newspackBlocksModalCheckout.checkout_nonce),R(o)}),function(e,t){e.checkoutComplete?t():e.addEventListener("checkout-complete",t)}(o,()=>{window.newspackRAS.push(["checkout_completed",a]),window?.newspackReaderActivation?.refreshNewslettersSignupModal&&window?.newspackReaderActivation?.getReader()?.email&&window.newspackReaderActivation.refreshNewslettersSignupModal(window.newspackReaderActivation.getReader().email),I("small"),N(newspackBlocksModal.labels.thankyou_modal_title),R(o),e(t.querySelector(`.${y}`)),u()}),function(e,t){e.checkoutPlaceOrderCriticalError?t():e.addEventListener("checkout-place-order-critical-error",t)}(o,()=>{var e;(e=b)&&(D(),q.style.display="none",t.initialErrors=newspackBlocksModal.labels.critical_error,e.requestSubmit(e.querySelector('button[type="submit"]')),u())})},()=>{q.style.display="flex"});const M=e=>new Promise((t,n)=>{const o=new URLSearchParams(e);o.append("action","modal_checkout_request"),fetch(newspackBlocksModal.ajax_url+"?"+o.toString()).then(e=>{e.ok||n(e),e.json().then(e=>{t(e.url)}).catch(n)}).catch(n)}),C=()=>"undefined"!=typeof newspack_ras_config&&!newspack_ras_config?.is_logged_in&&!window?.newspackReaderActivation?.getReader?.()?.authenticated&&newspackBlocksModal?.is_registration_required&&window?.newspackReaderActivation?.openAuthModal,x=t=>{const n=!newspackBlocksModal.has_unsupported_payment_gateway;n||t.preventDefault();const o=t.target;o.classList.add("modal-processing"),function(e){if(!e||"function"!=typeof e.querySelector)return!1;if(e.closest(".newspack-content-gate__gate"))return!1;const t=function(){let e,t;try{e=window.sessionStorage.getItem("newspack_cta_attribution")}catch(e){return null}if(!e)return null;try{t=JSON.parse(e)}catch(e){return null}return t&&1===t.v&&p[t.type]&&t.id?"number"!=typeof t.ts||Date.now()-t.ts>18e5?null:t:null}();if(!t)return!1;const n=p[t.type];if(e.querySelector(`input[name="${n}"]`))return!1;const o=document.createElement("input");o.type="hidden",o.name=n,o.value=t.id,e.prepend(o)}(o);const u=i(o);if(u.newspack_donate){const e=u.donation_frequency,t=[...o.querySelectorAll(`.donation-tier__${e}, .donation-frequency__${e}`)],n=u.donation_tier_index;let c,a;n?(c=t[n],a=u[`donation_value_${e}`]):(c=t[0],u[`donation_value_${e}_untiered`]?a=u[`donation_value_${e}_untiered`]:(a=u[`donation_value_${e}`],"other"===a&&(a=u[`donation_value_${e}_other`])));const r=i(c);for(const e in r)u[e]=r[e];u.amount=a,u.price_summary=u.summary_template.replace("{{PRICE}}",function(e,t="USD"){return parseFloat(e).toLocaleString(document.documentElement.lang,{style:"currency",currency:t,currencyDisplay:"narrowSymbol"})}(u.amount,u.currency))}u&&Object.keys(u).forEach(e=>{0===o.querySelectorAll('input[name="'+e+'"]').length&&o.prepend(a(e,u[e]))}),u.variation_id||(A=t.submitter);const d=document.querySelectorAll(`.${w}`);if(d.forEach(e=>{(C()||n)&&S(e)}),u.is_grouped||u.is_variable&&!u.variation_id){const n=[...d].find(e=>e.dataset.productId===u.product_id);if(n)return n.querySelectorAll(`form[target="${_}"]`).forEach(e=>{["after_success_behavior","after_success_url","after_success_button_label","gate_post_id","newspack_popup_id","prompt_title"].forEach(t=>{0===e.querySelectorAll('input[name="'+t+'"]').length&&e.prepend(a(t,u[t]))});const t=l(e);t&&Object.keys(t).forEach(n=>{0===e.querySelectorAll('input[name="'+n+'"]').length&&e.prepend(a(n,t[n]))})}),t.preventDefault(),o.classList.remove("modal-processing"),T(n),e(n,!1),v||c(u),void document.getElementById("newspack_modal_checkout").setAttribute("data-checkout",JSON.stringify(u))}if(n||C()){if(o.classList.remove("modal-processing"),v||c(u),v=!0,C()){t.preventDefault();const e=u.price_summary,o=e?`<div class="order-details-summary ${m}__box ${m}__box--text-center"><p><strong>${e}</strong></p></div>`:"",c=M(u);c.then(e=>{window.newspackReaderActivation?.setPendingCheckout?.(e)}),window.newspackReaderActivation.openAuthModal({title:newspackBlocksModal.labels.auth_modal_title,onSuccess:(e,t)=>{c.then(e=>{t?.registered&&n&&(e+=`&${newspackBlocksModal.checkout_registration_flag}=1`),n?r(B(e)):M(u).then(window.location.href=e)}).catch(e=>{console.warn("Unable to generate cart:",e),D()})},onError:()=>{D()},onDismiss:()=>{s(u),v=!1,document.getElementById("newspack_modal_checkout").removeAttribute("data-checkout")},skipSuccess:!0,skipNewslettersSignup:!0,labels:{signin:{title:newspackBlocksModal.labels.signin_modal_title},register:{title:newspackBlocksModal.labels.register_modal_title}},content:o,trigger:t.submitter,closeOnSuccess:n})}else O(),document.getElementById("newspack_modal_checkout").setAttribute("data-checkout",JSON.stringify(u));b=o}else M(u).then(e=>{window.location.href=e}),(!u.is_variable||u.variation_id)&&o.querySelectorAll("button[type=submit]:focus").forEach(e=>{e.classList.add("non-modal-checkout-loading");const t=e.innerHTML;e.innerHTML="<span>"+t+"</span>"})},B=e=>{const t=document.createElement("form");t.method="POST",t.action=e,t.target=_,t.style.display="none";const n=document.createElement("button");return n.setAttribute("type","submit"),t.appendChild(n),document.body.appendChild(t),t.addEventListener("submit",x),t},P=new ResizeObserver(e=>{if(!e||!e.length)return;if(!$.contentDocument)return;const o=e[0].contentRect;if(o){const e=.01*Math.max(document.documentElement.clientHeight,window.innerHeight||0)*90-(t.querySelector(`.${y}__header`)?.offsetHeight||0),c=o.top+o.bottom,a=Math.min(c,e);if(0===a)return void($.style.visibility="hidden");n.style.height=a+"px",$.style.height=a+"px"}}),D=()=>{const e=$?.contentDocument?.querySelector(`#${h}`),o=e?.querySelector('input[name="after_success_url"]'),c=e?.querySelector('input[name="after_success_behavior"]'),a=document?.querySelector(".newspack-newsletters-signup-modal"),r=i(e?.querySelector("#modal-checkout-product-details"));e?.checkoutComplete||(async()=>{const e=new FormData;newspackBlocksModal.has_unsupported_payment_gateway||e.append("modal_checkout","1"),e.append("action","abandon_modal_checkout"),e.append("_wpnonce",t.checkout_nonce),t.checkout_nonce=null;try{await fetch(newspackBlocksModal.ajax_url,{method:"POST",body:e})}catch(e){console.warn("Unable to empty cart:",e)}})();const l=!($.contentDocument&&o&&c&&e?.checkoutComplete);if((l||a)&&(q.style.display="flex",$&&n.contains($)&&($._ready=!1,$.src="about:blank",$.style.height=L,$.style.visibility="hidden",n.style.height=L,n.removeChild($)),P&&P.disconnect(),document.querySelectorAll(`.${y}-container`).forEach(e=>S(e)),A&&A.focus(),document.dispatchEvent(E)),e?.checkoutComplete){const e=()=>{if(o&&c){const e=o.getAttribute("value"),t=c.getAttribute("value");if("custom"===t)window.location.href=e;else if("referrer"===t){const e=document.referrer;let t=!1;if(e)try{new URL(e).origin===window.location.origin&&(window.location.href=e,t=!0)}catch(e){}t||window.history.back()}}window?.newspackReaderActivation?.setPendingCheckout?.(),v=!1};"subscription_switch"!==r.action_type&&window?.newspackReaderActivation?.openNewslettersSignupModal?window.newspackReaderActivation.openNewslettersSignupModal({onSuccess:e,onError:e,closeOnSuccess:l}):e(),l&&(g=newspackBlocksModal.labels.checkout_modal_title,I(),N(g))}else window?.newspackReaderActivation?.setPendingCheckout?.(),s(),v=!1,document.getElementById("newspack_modal_checkout").removeAttribute("data-checkout");document.removeEventListener("keydown",U)},O=o=>{o&&($.src=o),q.style.display="flex",T(t),n.appendChild($),t.addEventListener("click",e=>{e.target===t&&D()}),e(t,$),document.addEventListener("keydown",U)},T=e=>{window.newspackReaderActivation?.overlays&&(e.overlayId=window.newspackReaderActivation?.overlays.add()),e.setAttribute("data-state","open"),document.body.style.overflow="hidden"},N=e=>{const n=t.querySelector(`.${y}__header h2`);n&&(n.innerText=e)},I=(e="default")=>{const n=t.querySelector(`.${y}`);n&&("small"===e?n.classList.add(`${y}--small`):n.classList.remove(`${y}--small`))};t.querySelectorAll(`.${y}__close`).forEach(e=>{e.addEventListener("click",e=>{e.preventDefault(),D()})}),document.querySelectorAll(".newspack-blocks__modal-variation").forEach(e=>{e.addEventListener("click",t=>{t.target===e&&D()}),e.querySelectorAll(`.${y}__close`).forEach(e=>{e.addEventListener("click",e=>{e.preventDefault(),D()})})});const U=e=>{"Escape"===e.key&&D()};document.querySelectorAll(".wpbnbd.wpbnbd--platform-wc, .wp-block-newspack-blocks-checkout-button, .newspack-blocks__modal-variation").forEach(e=>{e.querySelectorAll("form").forEach(e=>{newspackBlocksModal.has_unsupported_payment_gateway||e.prepend(o.cloneNode()),e.target=_,e.addEventListener("submit",x)})}),(()=>{const e=new URLSearchParams(window.location.search);if(!e.has("checkout"))return;let t=!0;const n=e.get("type");if("donate"===n){const t=e.get("layout"),n=e.get("frequency"),o=e.get("amount"),c=e.get("other");t&&n&&o&&((e,t,n,o=null)=>{let c;document.querySelectorAll(".wpbnbd.wpbnbd--platform-wc form").forEach(a=>{const r=a.querySelector(`input[name="donation_frequency"][value="${t}"]`);if(r)if("tiered"===e){const e=document.querySelector(`button[data-frequency-slug="${t}"]`);if(!e)return;e.click();const o=a.querySelector(`button[type="submit"][name="donation_value_${t}"][value="${n}"]`);if(!o)return;o.click()}else{const i="untiered"===e?a.querySelector(`input[name="donation_value_${t}_untiered"]`):a.querySelector(`input[name="donation_value_${t}"][value="${n}"]`);if(r&&i){if(r.checked=!0,"untiered"===e)i.value=n;else if("other"===n){i.click();const e=a.querySelector(`input[name="donation_value_${t}_other"]`);e&&o&&(e.value=o)}else i.checked=!0;c=a}}}),c&&r(c)})(t,n,o,c)}else if("checkout_button"===n){const n=e.get("product_id"),o=e.get("variation_id");n?t=((e,t=null)=>{const n=function(e,t,n,o={}){const{allowProductOnlyFallback:c=!1}=o;if(null==n||""===String(n))return u(e,t,null);const a=u(e,t,n);if(a)return a;const r=function(e,t,n,o={}){const{variationModalClassPrefix:c,iframeName:a}=o,r=[...e.querySelectorAll(`.${c}`)].find(e=>String(e.dataset.productId)===String(t));if(!r)return null;const i=r.querySelectorAll("form"),s=a?[...i].find(e=>e.getAttribute("target")===a):i[0];if(!s)return null;const l=[...s.querySelectorAll('input[type="radio"][name="product_id"]')].find(e=>String(e.value)===String(n));return l?(l.checked=!0,s):null}(e,t,n,o);return r?(function(e,t,n=d){if(!e||!t)return;const o=t.ownerDocument,c=new FormData(e);n.forEach(e=>{if(t.querySelector(`input[name="${e}"]`))return;const n=c.getAll(e).filter(e=>"string"==typeof e&&e);if(!n.length)return;const a=o.createElement("input");a.type="hidden",a.name=e,a.value=n[n.length-1],t.prepend(a)})}(u(e,t,null),r),r):c?u(e,t,null):null}(document,e,t,{variationModalClassPrefix:w,iframeName:_});if(n)return r(n),!0;const o=`Newspack modal checkout: no checkout form found for product_id "${e}"`+(t?` and variation_id "${t}"`:"")+". The checkout was not triggered.";return console.warn(o),!1})(n,o):(t=!1,console.warn("Newspack modal checkout: checkout_button trigger is missing product_id. The checkout was not triggered."))}else{const e=window.newspackReaderActivation?.getPendingCheckout?.();e&&r(B(e))}t&&window.history.replaceState(null,null,window.location.pathname)})(),window.newspackOpenModalCheckout=({url:e=null,title:t=null,actionType:n=null,afterSuccess:o={},onCheckoutComplete:c=null,onClose:a=null})=>{if(g=t||newspackBlocksModal.labels.checkout_modal_title,N(g),(e=new URL(e||newspackBlocksModal.checkout_url)).searchParams.has("my_account_checkout")&&e.searchParams.delete("my_account_checkout"),e.searchParams.has("modal_checkout")||e.searchParams.set("modal_checkout","1"),n&&e.searchParams.set("action_type",n),o?.url&&e.searchParams.set("after_success_url",o.url),(o?.behavior||o?.url)&&e.searchParams.set("after_success_behavior",o.behavior||"custom"),o?.buttonLabel&&e.searchParams.set("after_success_button_label",o.buttonLabel),c){const e=({detail:{action:e,data:t}})=>{"checkout_completed"===e&&c(t)};window.newspackRAS.push(t=>{t.on("activity",e);const n=()=>{t.off("activity",e),document.removeEventListener("checkout-closed",n)};document.addEventListener("checkout-closed",n)})}if(a){const e=()=>{a(),document.removeEventListener("checkout-closed",e)};document.addEventListener("checkout-closed",e)}O(e.toString())},window.newspackCloseModalCheckout=D},"undefined"!=typeof document&&("complete"!==document.readyState&&"interactive"!==document.readyState?document.addEventListener("DOMContentLoaded",q):q())})();
1
+ (()=>{"use strict";function e(e,t=!1){const n=e.querySelectorAll('button, [href], input:not([type="hidden"]), select, textarea, [tabindex]:not([tabindex="-1"])');if(0===n.length)return!1;const o=n?.[0];let c;o.focus(),t?(document.addEventListener("keydown",function(e){if(("Tab"===e.key||9===e.keyCode)&&e.shiftKey&&document.activeElement===o){const n=t.contentWindow.document,o=n.getElementById("checkout-after-success");c=null!==o?o:n.getElementById("checkout_cancel"),c.focus(),e.preventDefault()}}),document.getElementById("newspack-a11y-last-element").addEventListener("focus",()=>{o.focus()})):(c=n[n.length-1],document.addEventListener("keydown",function(e){("Tab"===e.key||9===e.keyCode)&&(e.shiftKey?document.activeElement===o&&(c.focus(),e.preventDefault()):document.activeElement===c&&(o.focus(),e.preventDefault()))}))}const t=(e,t={})=>({...t,action:e}),n=["action","action_type","amount","currency","product_id","product_type","variation_id","variation_ids","is_variable","is_grouped","child_ids","price_summary","newspack_popup_id","prompt_title","gate_post_id","recurrence","referrer"],o=(e,t="np_modal_checkout_interaction")=>{if("function"==typeof window.gtag&&e){const o={};for(const t of n)e[t]&&("boolean"==typeof e[t]?e[t]=e[t]?"yes":"no":"true"===e[t]?e[t]="yes":"false"===e[t]&&(e[t]="no"),o[t]=e[t].toString());window.gtag("event",t,o)}},c=e=>{if("function"!=typeof window.gtag)return;let n="opened";const{amount:c="",is_variable:a="",is_grouped:r="",price:i="",variation_id:s=""}=e,l={...e};(c||i)&&(l.amount=c||i),a&&!s&&(n="opened_variations"),r&&(n="opened_grouped");const u=t(n,l);o(u)};function a(e,t=null){const n=document.createElement("input");return n.type="hidden",n.name=e,t&&(n.value=t),n}function r(e){e.requestSubmit(e.querySelector('button[type="submit"]'))}function i(e){const t="string"==typeof e?document.getElementById(e):e;if(!t)return console.warn("No container found for checkout data"),{};let n={};if("FORM"===t.tagName){const e=new FormData(t);n=Object.fromEntries(e)}const o=t.dataset.checkout;if(!o)return console.warn("No checkout data found"),n;try{n={...n,...JSON.parse(o)}}catch(e){console.warn("Error parsing checkout data")}const c=new URL(t.ownerDocument.defaultView.location.href);return c.searchParams.get("action_type")&&(n.action_type=c.searchParams.get("action_type")),n}const s=e=>{if("function"!=typeof window.gtag)return;e=e||i("newspack_modal_checkout");const n=t("dismissed",e);o(n)};function l(e){const t=e&&e.dataset?e.dataset.checkout:null;if(!t)return null;try{return JSON.parse(t)}catch(e){return null}}function u(e,t,n=null){const o=e.querySelectorAll(".wp-block-newspack-blocks-checkout-button"),c=null!=n&&""!==String(n);let a=null;return o.forEach(e=>{if(a)return;const o=e.querySelector("form"),r=l(o);r&&String(r.product_id)===String(t)&&(c&&String(r.variation_id)!==String(n)||(a=o))}),a}const d=["after_success_behavior","after_success_url","after_success_button_label","after_success_token","gate_post_id","newspack_popup_id","prompt_title"];const p={gate:"gate_post_id",prompt:"newspack_popup_id"};const m=newspackBlocksModal.newspack_class_prefix,_="newspack_modal_checkout_iframe",h="newspack_modal_checkout_container",y=`${m}__modal`,w="newspack-blocks__modal-variation",f=`${m}__processing-payment-text`,k=newspackBlocksModal.processing_payment_messages;let v=!1,g=newspackBlocksModal.labels.checkout_modal_title,b=null;const S=e=>{e.overlayId&&window.newspackReaderActivation?.overlays&&window.newspackReaderActivation?.overlays.remove(e.overlayId),e.setAttribute("data-state","closed"),document.body.style.overflow="auto"};window.onpageshow=e=>{e.persisted&&(document.querySelectorAll(".modal-processing").forEach(e=>e.classList.remove("modal-processing")),document.querySelectorAll(".non-modal-checkout-loading").forEach(e=>e.classList.remove("non-modal-checkout-loading")),document.querySelectorAll(`.${y}-container`).forEach(e=>S(e)))};const E=new CustomEvent("checkout-closed");var q;window.newspackRAS=window.newspackRAS||[],q=()=>{const t=document.querySelector("#newspack_modal_checkout");if(!t)return;const n=t.querySelector(`.${y}__content`),o=a("modal_checkout","1"),q=n.querySelector(`.${m}__spinner`);let A=document.querySelector(".newspack-reader__account-link")?.[0];const L="600px",$=document.createElement("iframe");$.name=_,$.style.height=L,$.style.visibility="hidden";const R=e=>{P.observe(e),"none"!==q.style.display&&(q.style.display="none"),"visible"!==$.style.visibility&&($.style.visibility="visible"),$._ready=!0};!function(e,t,n){e._ready=!1,e._readyTimer&&clearTimeout(e._readyTimer);let o=!1,c="";function a(){o||(o=!0,clearTimeout(e._readyTimer),t.call(this))}function r(){"complete"===this.readyState&&a.call(this)}function i(){e._ready=!1,n&&n(),e._readyTimer&&clearTimeout(e._readyTimer);const t=e.contentDocument||e.contentWindow?.document;t&&(t.removeEventListener("DOMContentLoaded",a),t.removeEventListener("readystatechange",r))}function s(){if(e._ready)return void i();const t=e.contentDocument||e.contentWindow?.document;t&&0!==t.URL.indexOf("about:")?"complete"===t?.readyState?a.call(t):(t.addEventListener("DOMContentLoaded",a),t.addEventListener("readystatechange",r)):e._readyTimer=setTimeout(s,10)}e._observer||(e._observer=new MutationObserver(e=>{e.forEach(e=>{"attributes"===e.type&&"src"===e.attributeName&&(o=!1,i(),s())})}),e._observer.observe(e,{attributes:!0})),e._locationObserver||(e._locationObserver=setInterval(function(){const t=e.contentDocument||e.contentWindow?.document;t&&t.URL!==c&&(c=t.URL,o=!1,i(),s())},50)),s()}($,function(){const n=$.contentWindow?.location;if(window.newspackReaderActivation&&n?.href?.includes("order-received")){const e=window.newspackReaderActivation,t=new Proxy(new URLSearchParams(n.search),{get:(e,t)=>e.get(t)});t.email&&(e.setReaderEmail(t.email),e.setAuthenticated(!0))}const o=$?.contentDocument?.querySelector(`#${h}`);if(!o)return;const c=o.querySelector("#modal-checkout-product-details"),a=i(c),r=document.createElement("p");r.classList.add(f);let s=[];const l=()=>{s.forEach(e=>clearTimeout(e)),s=[]},u=()=>{q.style.display="none",l(),q.querySelectorAll(`.${f}`).forEach(e=>e.remove())};!function(e,t){e.checkoutCancel?t():e.addEventListener("checkout-cancel",t)}(o,()=>{D()}),function(e,t){e.checkoutPlaceOrderStart?t():e.addEventListener("checkout-place-order-start",t)}(o,e=>{q.querySelectorAll(`.${f}`).forEach(e=>e.remove()),q.style.display="flex",l(),r.textContent=k[0]?.text??"",k.slice(1).forEach(({text:t,delay:n})=>{const o=setTimeout(()=>{e.target.dispatchEvent(new CustomEvent("checkout-place-order-processing")),r.textContent=t},n);s.push(o)}),q.appendChild(r)}),function(e,t){e.checkoutPlaceOrderError?t():e.addEventListener("checkout-place-order-error",t)}(o,u),function(e,t){e.checkoutReady?t():e.addEventListener("checkout-ready",t)}(o,()=>{const e=c?.querySelector("strong");if(e&&(e.textContent=a.price_summary),t.initialErrors){const e=document.createElement("div");e.classList.add("woocommerce-error"),e.textContent=t.initialErrors,o.prepend(e),delete t.initialErrors}I(),N(g),$.contentWindow?.newspackBlocksModalCheckout?.checkout_nonce&&(t.checkout_nonce=$.contentWindow.newspackBlocksModalCheckout.checkout_nonce),R(o)}),function(e,t){e.checkoutComplete?t():e.addEventListener("checkout-complete",t)}(o,()=>{window.newspackRAS.push(["checkout_completed",a]),window?.newspackReaderActivation?.refreshNewslettersSignupModal&&window?.newspackReaderActivation?.getReader()?.email&&window.newspackReaderActivation.refreshNewslettersSignupModal(window.newspackReaderActivation.getReader().email),I("small"),N(newspackBlocksModal.labels.thankyou_modal_title),R(o),e(t.querySelector(`.${y}`)),u()}),function(e,t){e.checkoutPlaceOrderCriticalError?t():e.addEventListener("checkout-place-order-critical-error",t)}(o,()=>{var e;(e=b)&&(D(),q.style.display="none",t.initialErrors=newspackBlocksModal.labels.critical_error,e.requestSubmit(e.querySelector('button[type="submit"]')),u())})},()=>{q.style.display="flex"});const M=e=>new Promise((t,n)=>{const o=new URLSearchParams(e);o.append("action","modal_checkout_request"),fetch(newspackBlocksModal.ajax_url+"?"+o.toString()).then(e=>{e.ok||n(e),e.json().then(e=>{t(e.url)}).catch(n)}).catch(n)}),C=()=>"undefined"!=typeof newspack_ras_config&&!newspack_ras_config?.is_logged_in&&!window?.newspackReaderActivation?.getReader?.()?.authenticated&&newspackBlocksModal?.is_registration_required&&window?.newspackReaderActivation?.openAuthModal,x=t=>{const n=!newspackBlocksModal.has_unsupported_payment_gateway;n||t.preventDefault();const o=t.target;o.classList.add("modal-processing"),function(e){if(!e||"function"!=typeof e.querySelector)return!1;if(e.closest(".newspack-content-gate__gate"))return!1;const t=function(){let e,t;try{e=window.sessionStorage.getItem("newspack_cta_attribution")}catch(e){return null}if(!e)return null;try{t=JSON.parse(e)}catch(e){return null}return t&&1===t.v&&p[t.type]&&t.id?"number"!=typeof t.ts||Date.now()-t.ts>18e5?null:t:null}();if(!t)return!1;const n=p[t.type];if(e.querySelector(`input[name="${n}"]`))return!1;const o=document.createElement("input");o.type="hidden",o.name=n,o.value=t.id,e.prepend(o)}(o);const u=i(o);if(u.newspack_donate){const e=u.donation_frequency,t=[...o.querySelectorAll(`.donation-tier__${e}, .donation-frequency__${e}`)],n=u.donation_tier_index;let c,a;n?(c=t[n],a=u[`donation_value_${e}`]):(c=t[0],u[`donation_value_${e}_untiered`]?a=u[`donation_value_${e}_untiered`]:(a=u[`donation_value_${e}`],"other"===a&&(a=u[`donation_value_${e}_other`])));const r=i(c);for(const e in r)u[e]=r[e];u.amount=a,u.price_summary=u.summary_template.replace("{{PRICE}}",function(e,t="USD"){return parseFloat(e).toLocaleString(document.documentElement.lang,{style:"currency",currency:t,currencyDisplay:"narrowSymbol"})}(u.amount,u.currency))}u&&Object.keys(u).forEach(e=>{0===o.querySelectorAll('input[name="'+e+'"]').length&&o.prepend(a(e,u[e]))}),u.variation_id||(A=t.submitter);const h=document.querySelectorAll(`.${w}`);if(h.forEach(e=>{(C()||n)&&S(e)}),u.is_grouped||u.is_variable&&!u.variation_id){const n=[...h].find(e=>e.dataset.productId===u.product_id);if(n)return n.querySelectorAll(`form[target="${_}"]`).forEach(e=>{d.forEach(t=>{0===e.querySelectorAll('input[name="'+t+'"]').length&&e.prepend(a(t,u[t]))});const t=l(e);t&&Object.keys(t).forEach(n=>{0===e.querySelectorAll('input[name="'+n+'"]').length&&e.prepend(a(n,t[n]))})}),t.preventDefault(),o.classList.remove("modal-processing"),T(n),e(n,!1),v||c(u),void document.getElementById("newspack_modal_checkout").setAttribute("data-checkout",JSON.stringify(u))}if(n||C()){if(o.classList.remove("modal-processing"),v||c(u),v=!0,C()){t.preventDefault();const e=u.price_summary,o=e?`<div class="order-details-summary ${m}__box ${m}__box--text-center"><p><strong>${e}</strong></p></div>`:"",c=M(u);c.then(e=>{window.newspackReaderActivation?.setPendingCheckout?.(e)}),window.newspackReaderActivation.openAuthModal({title:newspackBlocksModal.labels.auth_modal_title,onSuccess:(e,t)=>{c.then(e=>{t?.registered&&n&&(e+=`&${newspackBlocksModal.checkout_registration_flag}=1`),n?r(B(e)):M(u).then(window.location.href=e)}).catch(e=>{console.warn("Unable to generate cart:",e),D()})},onError:()=>{D()},onDismiss:()=>{s(u),v=!1,document.getElementById("newspack_modal_checkout").removeAttribute("data-checkout")},skipSuccess:!0,skipNewslettersSignup:!0,labels:{signin:{title:newspackBlocksModal.labels.signin_modal_title},register:{title:newspackBlocksModal.labels.register_modal_title}},content:o,trigger:t.submitter,closeOnSuccess:n})}else O(),document.getElementById("newspack_modal_checkout").setAttribute("data-checkout",JSON.stringify(u));b=o}else M(u).then(e=>{window.location.href=e}),(!u.is_variable||u.variation_id)&&o.querySelectorAll("button[type=submit]:focus").forEach(e=>{e.classList.add("non-modal-checkout-loading");const t=e.innerHTML;e.innerHTML="<span>"+t+"</span>"})},B=e=>{const t=document.createElement("form");t.method="POST",t.action=e,t.target=_,t.style.display="none";const n=document.createElement("button");return n.setAttribute("type","submit"),t.appendChild(n),document.body.appendChild(t),t.addEventListener("submit",x),t},P=new ResizeObserver(e=>{if(!e||!e.length)return;if(!$.contentDocument)return;const o=e[0].contentRect;if(o){const e=.01*Math.max(document.documentElement.clientHeight,window.innerHeight||0)*90-(t.querySelector(`.${y}__header`)?.offsetHeight||0),c=o.top+o.bottom,a=Math.min(c,e);if(0===a)return void($.style.visibility="hidden");n.style.height=a+"px",$.style.height=a+"px"}}),D=()=>{const e=$?.contentDocument?.querySelector(`#${h}`),o=e?.querySelector('input[name="after_success_url"]'),c=e?.querySelector('input[name="after_success_behavior"]'),a=document?.querySelector(".newspack-newsletters-signup-modal"),r=i(e?.querySelector("#modal-checkout-product-details"));e?.checkoutComplete||(async()=>{const e=new FormData;newspackBlocksModal.has_unsupported_payment_gateway||e.append("modal_checkout","1"),e.append("action","abandon_modal_checkout"),e.append("_wpnonce",t.checkout_nonce),t.checkout_nonce=null;try{await fetch(newspackBlocksModal.ajax_url,{method:"POST",body:e})}catch(e){console.warn("Unable to empty cart:",e)}})();const l=!($.contentDocument&&o&&c&&e?.checkoutComplete);if((l||a)&&(q.style.display="flex",$&&n.contains($)&&($._ready=!1,$.src="about:blank",$.style.height=L,$.style.visibility="hidden",n.style.height=L,n.removeChild($)),P&&P.disconnect(),document.querySelectorAll(`.${y}-container`).forEach(e=>S(e)),A&&A.focus(),document.dispatchEvent(E)),e?.checkoutComplete){const e=()=>{if(o&&c){const e=o.getAttribute("value"),t=c.getAttribute("value");if("custom"===t)window.location.href=e;else if("referrer"===t){const e=document.referrer;let t=!1;if(e)try{new URL(e).origin===window.location.origin&&(window.location.href=e,t=!0)}catch(e){}t||window.history.back()}}window?.newspackReaderActivation?.setPendingCheckout?.(),v=!1};"subscription_switch"!==r.action_type&&window?.newspackReaderActivation?.openNewslettersSignupModal?window.newspackReaderActivation.openNewslettersSignupModal({onSuccess:e,onError:e,closeOnSuccess:l}):e(),l&&(g=newspackBlocksModal.labels.checkout_modal_title,I(),N(g))}else window?.newspackReaderActivation?.setPendingCheckout?.(),s(),v=!1,document.getElementById("newspack_modal_checkout").removeAttribute("data-checkout");document.removeEventListener("keydown",U)},O=o=>{o&&($.src=o),q.style.display="flex",T(t),n.appendChild($),t.addEventListener("click",e=>{e.target===t&&D()}),e(t,$),document.addEventListener("keydown",U)},T=e=>{window.newspackReaderActivation?.overlays&&(e.overlayId=window.newspackReaderActivation?.overlays.add()),e.setAttribute("data-state","open"),document.body.style.overflow="hidden"},N=e=>{const n=t.querySelector(`.${y}__header h2`);n&&(n.innerText=e)},I=(e="default")=>{const n=t.querySelector(`.${y}`);n&&("small"===e?n.classList.add(`${y}--small`):n.classList.remove(`${y}--small`))};t.querySelectorAll(`.${y}__close`).forEach(e=>{e.addEventListener("click",e=>{e.preventDefault(),D()})}),document.querySelectorAll(".newspack-blocks__modal-variation").forEach(e=>{e.addEventListener("click",t=>{t.target===e&&D()}),e.querySelectorAll(`.${y}__close`).forEach(e=>{e.addEventListener("click",e=>{e.preventDefault(),D()})})});const U=e=>{"Escape"===e.key&&D()};document.querySelectorAll(".wpbnbd.wpbnbd--platform-wc, .wp-block-newspack-blocks-checkout-button, .newspack-blocks__modal-variation").forEach(e=>{e.querySelectorAll("form").forEach(e=>{newspackBlocksModal.has_unsupported_payment_gateway||e.prepend(o.cloneNode()),e.target=_,e.addEventListener("submit",x)})}),(()=>{const e=new URLSearchParams(window.location.search);if(!e.has("checkout"))return;let t=!0;const n=e.get("type");if("donate"===n){const t=e.get("layout"),n=e.get("frequency"),o=e.get("amount"),c=e.get("other");t&&n&&o&&((e,t,n,o=null)=>{let c;document.querySelectorAll(".wpbnbd.wpbnbd--platform-wc form").forEach(a=>{const r=a.querySelector(`input[name="donation_frequency"][value="${t}"]`);if(r)if("tiered"===e){const e=document.querySelector(`button[data-frequency-slug="${t}"]`);if(!e)return;e.click();const o=a.querySelector(`button[type="submit"][name="donation_value_${t}"][value="${n}"]`);if(!o)return;o.click()}else{const i="untiered"===e?a.querySelector(`input[name="donation_value_${t}_untiered"]`):a.querySelector(`input[name="donation_value_${t}"][value="${n}"]`);if(r&&i){if(r.checked=!0,"untiered"===e)i.value=n;else if("other"===n){i.click();const e=a.querySelector(`input[name="donation_value_${t}_other"]`);e&&o&&(e.value=o)}else i.checked=!0;c=a}}}),c&&r(c)})(t,n,o,c)}else if("checkout_button"===n){const n=e.get("product_id"),o=e.get("variation_id");n?t=((e,t=null)=>{const n=function(e,t,n,o={}){const{allowProductOnlyFallback:c=!1}=o;if(null==n||""===String(n))return u(e,t,null);const a=u(e,t,n);if(a)return a;const r=function(e,t,n,o={}){const{variationModalClassPrefix:c,iframeName:a}=o,r=[...e.querySelectorAll(`.${c}`)].find(e=>String(e.dataset.productId)===String(t));if(!r)return null;const i=r.querySelectorAll("form"),s=a?[...i].find(e=>e.getAttribute("target")===a):i[0];if(!s)return null;const l=[...s.querySelectorAll('input[type="radio"][name="product_id"]')].find(e=>String(e.value)===String(n));return l?(l.checked=!0,s):null}(e,t,n,o);return r?(function(e,t,n=d){if(!e||!t)return;const o=t.ownerDocument,c=new FormData(e);n.forEach(e=>{if(t.querySelector(`input[name="${e}"]`))return;const n=c.getAll(e).filter(e=>"string"==typeof e&&e);if(!n.length)return;const a=o.createElement("input");a.type="hidden",a.name=e,a.value=n[n.length-1],t.prepend(a)})}(u(e,t,null),r),r):c?u(e,t,null):null}(document,e,t,{variationModalClassPrefix:w,iframeName:_});if(n)return r(n),!0;const o=`Newspack modal checkout: no checkout form found for product_id "${e}"`+(t?` and variation_id "${t}"`:"")+". The checkout was not triggered.";return console.warn(o),!1})(n,o):(t=!1,console.warn("Newspack modal checkout: checkout_button trigger is missing product_id. The checkout was not triggered."))}else{const e=window.newspackReaderActivation?.getPendingCheckout?.();e&&r(B(e))}t&&window.history.replaceState(null,null,window.location.pathname)})(),window.newspackOpenModalCheckout=({url:e=null,title:t=null,actionType:n=null,afterSuccess:o={},onCheckoutComplete:c=null,onClose:a=null})=>{if(g=t||newspackBlocksModal.labels.checkout_modal_title,N(g),(e=new URL(e||newspackBlocksModal.checkout_url)).searchParams.has("my_account_checkout")&&e.searchParams.delete("my_account_checkout"),e.searchParams.has("modal_checkout")||e.searchParams.set("modal_checkout","1"),n&&e.searchParams.set("action_type",n),o?.url&&e.searchParams.set("after_success_url",o.url),(o?.behavior||o?.url)&&e.searchParams.set("after_success_behavior",o.behavior||"custom"),o?.buttonLabel&&e.searchParams.set("after_success_button_label",o.buttonLabel),c){const e=({detail:{action:e,data:t}})=>{"checkout_completed"===e&&c(t)};window.newspackRAS.push(t=>{t.on("activity",e);const n=()=>{t.off("activity",e),document.removeEventListener("checkout-closed",n)};document.addEventListener("checkout-closed",n)})}if(a){const e=()=>{a(),document.removeEventListener("checkout-closed",e)};document.addEventListener("checkout-closed",e)}O(e.toString())},window.newspackCloseModalCheckout=D},"undefined"!=typeof document&&("complete"!==document.readyState&&"interactive"!==document.readyState?document.addEventListener("DOMContentLoaded",q):q())})();
@@ -377,6 +377,7 @@ final class Modal_Checkout {
377
377
  $after_success_behavior = filter_input( INPUT_GET, 'after_success_behavior', FILTER_SANITIZE_SPECIAL_CHARS );
378
378
  $after_success_url = filter_input( INPUT_GET, 'after_success_url', FILTER_SANITIZE_URL );
379
379
  $after_success_button_label = filter_input( INPUT_GET, 'after_success_button_label', FILTER_SANITIZE_SPECIAL_CHARS );
380
+ $after_success_token = filter_input( INPUT_GET, 'after_success_token', FILTER_SANITIZE_SPECIAL_CHARS );
380
381
 
381
382
  if ( $variation_id ) {
382
383
  $product_id = $variation_id;
@@ -395,7 +396,7 @@ final class Modal_Checkout {
395
396
  wp_parse_str( $parsed_url['query'], $params );
396
397
  }
397
398
 
398
- $params = array_merge( $params, compact( 'after_success_behavior', 'after_success_url', 'after_success_button_label' ) );
399
+ $params = array_merge( $params, compact( 'after_success_behavior', 'after_success_url', 'after_success_button_label', 'after_success_token' ) );
399
400
 
400
401
  if ( function_exists( 'wpcom_vip_url_to_postid' ) ) {
401
402
  $referer_post_id = wpcom_vip_url_to_postid( $referer );
@@ -1198,35 +1199,300 @@ final class Modal_Checkout {
1198
1199
  */
1199
1200
  const AFTER_SUCCESS_BEHAVIORS = [ 'custom', 'referrer' ];
1200
1201
 
1202
+ /**
1203
+ * Reduce a post-checkout destination to a single comparable form.
1204
+ *
1205
+ * Signing and verifying have to agree on the exact string, and the value passes through
1206
+ * sanitising on its way between them, so both sides normalise here rather than each
1207
+ * doing their own.
1208
+ *
1209
+ * @param string $url The requested destination.
1210
+ *
1211
+ * @return string The normalised destination, or an empty string.
1212
+ */
1213
+ public static function normalize_after_success_url( $url ) {
1214
+ $url = sanitize_url( (string) $url );
1215
+
1216
+ if ( empty( $url ) ) {
1217
+ return '';
1218
+ }
1219
+
1220
+ // Core compares hosts case-sensitively; host names aren't. Rebuild from the parsed
1221
+ // parts rather than replacing the host in the string: the host can appear again
1222
+ // inside a query parameter, and a `user@host` authority never matches `://host` at
1223
+ // all, so a string replacement either rewrites too much or nothing.
1224
+ $parts = wp_parse_url( $url );
1225
+ if ( ! empty( $parts['host'] ) && strtolower( $parts['host'] ) !== $parts['host'] ) {
1226
+ $parts['host'] = strtolower( $parts['host'] );
1227
+ $url = self::build_url( $parts );
1228
+ }
1229
+
1230
+ return $url;
1231
+ }
1232
+
1233
+ /**
1234
+ * Reassemble a URL from `wp_parse_url()` parts.
1235
+ *
1236
+ * @param array $parts Parsed URL parts.
1237
+ *
1238
+ * @return string
1239
+ */
1240
+ private static function build_url( $parts ) {
1241
+ $user = $parts['user'] ?? '';
1242
+ $pass = isset( $parts['pass'] ) ? ':' . $parts['pass'] : '';
1243
+ $auth = $user ? $user . $pass . '@' : '';
1244
+
1245
+ // A destination with a host but no scheme is protocol-relative. Losing the `//` here
1246
+ // would turn it into a relative path, which changes where the reader lands and makes
1247
+ // this function non-idempotent — and the token signs a normalised value at mint and
1248
+ // normalises again at read, so idempotence is what makes it verify.
1249
+ $prefix = isset( $parts['scheme'] )
1250
+ ? $parts['scheme'] . '://'
1251
+ : ( isset( $parts['host'] ) ? '//' : '' );
1252
+
1253
+ return $prefix
1254
+ . $auth
1255
+ . ( $parts['host'] ?? '' )
1256
+ . ( isset( $parts['port'] ) ? ':' . $parts['port'] : '' )
1257
+ . ( $parts['path'] ?? '' )
1258
+ . ( isset( $parts['query'] ) ? '?' . $parts['query'] : '' )
1259
+ . ( isset( $parts['fragment'] ) ? '#' . $parts['fragment'] : '' );
1260
+ }
1261
+
1262
+ /**
1263
+ * Whether a post is published, read from the stored status.
1264
+ *
1265
+ * `get_post_status()` reports an attachment as `publish` whatever its stored status, so a
1266
+ * token could be minted from one and could not be revoked by unpublishing. Reading the
1267
+ * field directly returns the real status, and also steps around the `get_post_status`
1268
+ * filter, which would otherwise let any plugin move this gate.
1269
+ *
1270
+ * @param int $post_id The post to check.
1271
+ *
1272
+ * @return boolean
1273
+ */
1274
+ private static function is_published_post( $post_id ) {
1275
+ return 'publish' === get_post_field( 'post_status', (int) $post_id );
1276
+ }
1277
+
1278
+ /**
1279
+ * The post a block is being rendered for.
1280
+ *
1281
+ * `get_the_ID()` is empty outside the loop, which is where a block in a widget or a footer
1282
+ * template part renders. The queried object covers that, but only when it is a post: on an
1283
+ * archive it is a term, whose ID would otherwise be read as an unrelated post's.
1284
+ *
1285
+ * @return int Post ID, or 0.
1286
+ */
1287
+ private static function get_after_success_post_id() {
1288
+ $post_id = (int) get_the_ID();
1289
+
1290
+ if ( $post_id ) {
1291
+ return $post_id;
1292
+ }
1293
+
1294
+ $queried = get_queried_object();
1295
+
1296
+ return $queried instanceof WP_Post ? (int) $queried->ID : 0;
1297
+ }
1298
+
1299
+ /**
1300
+ * Sign a value for the post-checkout destination it belongs to.
1301
+ *
1302
+ * Namespaced so this never produces the same digest as another use of the same key —
1303
+ * `wp_hash()` with the auth salt also backs the magic-link and email-change secrets, and
1304
+ * these signatures are published in page HTML.
1305
+ *
1306
+ * @param string $payload The value to sign.
1307
+ *
1308
+ * @return string
1309
+ */
1310
+ private static function sign_after_success_payload( $payload ) {
1311
+ // The namespace prefix is what separates this from every other use of the same key and
1312
+ // algorithm. `Reader_Registration::get_frontend_registration_key()` also produces
1313
+ // `hash_hmac( 'sha256', …, wp_salt( 'auth' ) )` and publishes the result to the front
1314
+ // end, so nothing but this prefix distinguishes the two. Never register an integration
1315
+ // ID that begins with it.
1316
+ //
1317
+ // The blog ID is included because `wp_salt()` is network-scoped: without it, a token
1318
+ // minted on one site of a network verifies on every other site in that network.
1319
+ $namespace = 'newspack_blocks_after_success|' . get_current_blog_id() . '|';
1320
+
1321
+ return hash_hmac( 'sha256', $namespace . $payload, wp_salt( 'auth' ) );
1322
+ }
1323
+
1324
+ /**
1325
+ * Mint a token vouching for a post-checkout destination a block was configured with.
1326
+ *
1327
+ * Minted where the block renders, which is the last point this site knows the destination
1328
+ * came from its own content rather than from the request. Two properties matter:
1329
+ *
1330
+ * The destination travels *inside* the token rather than beside it. The token's alphabet
1331
+ * is URL-safe base64 plus a dot, so the sanitising the value meets in transit — which
1332
+ * variously deletes percent-encoded octets, drops non-ASCII bytes and HTML-encodes `&`
1333
+ * and `'` — cannot alter it. Signing the bare URL and hoping every transit point leaves
1334
+ * it alone is what this avoids.
1335
+ *
1336
+ * The token is bound to the post being rendered, and only published posts are signed, so
1337
+ * a token cannot be minted through the block-renderer REST route or a draft preview by
1338
+ * someone who can edit posts but not publish them.
1339
+ *
1340
+ * `hash_hmac` rather than a nonce: the token has to survive page caching and a reader who
1341
+ * signs in partway through checkout, and a nonce is bound to a user and a time window.
1342
+ *
1343
+ * @param string $url The destination to vouch for.
1344
+ * @param int $post_id The post being rendered. Defaults to the current post.
1345
+ *
1346
+ * @return string The token, or an empty string if there is nothing to vouch for.
1347
+ */
1348
+ public static function get_after_success_token( $url, $post_id = 0 ) {
1349
+ $url = self::normalize_after_success_url( $url );
1350
+
1351
+ if ( '' === $url ) {
1352
+ return '';
1353
+ }
1354
+
1355
+ $post_id = $post_id ? (int) $post_id : self::get_after_success_post_id();
1356
+
1357
+ if ( ! $post_id || ! self::is_published_post( $post_id ) ) {
1358
+ return '';
1359
+ }
1360
+
1361
+ $payload = self::encode_after_success_payload(
1362
+ [
1363
+ 'u' => $url,
1364
+ 'p' => $post_id,
1365
+ ]
1366
+ );
1367
+
1368
+ return $payload . '.' . self::sign_after_success_payload( $payload );
1369
+ }
1370
+
1371
+ /**
1372
+ * Read a destination back out of a token, if this site vouched for it.
1373
+ *
1374
+ * @param string $token The token offered with the request.
1375
+ *
1376
+ * @return string The destination, or an empty string if the token is not this site's.
1377
+ */
1378
+ public static function parse_after_success_token( $token ) {
1379
+ $token = (string) $token;
1380
+
1381
+ if ( '' === $token || false === strpos( $token, '.' ) ) {
1382
+ return '';
1383
+ }
1384
+
1385
+ list( $payload, $signature ) = explode( '.', $token, 2 );
1386
+
1387
+ if ( '' === $payload || '' === $signature ) {
1388
+ return '';
1389
+ }
1390
+
1391
+ if ( ! hash_equals( self::sign_after_success_payload( $payload ), $signature ) ) {
1392
+ return '';
1393
+ }
1394
+
1395
+ $claims = self::decode_after_success_payload( $payload );
1396
+
1397
+ if ( empty( $claims['u'] ) || empty( $claims['p'] ) ) {
1398
+ return '';
1399
+ }
1400
+
1401
+ // Checked at read time as well as at mint time: a post that has since been
1402
+ // unpublished should stop vouching for its destination.
1403
+ if ( ! self::is_published_post( (int) $claims['p'] ) ) {
1404
+ return '';
1405
+ }
1406
+
1407
+ return self::normalize_after_success_url( $claims['u'] );
1408
+ }
1409
+
1410
+ /**
1411
+ * Encode token claims into a form transit cannot alter.
1412
+ *
1413
+ * @param array $claims The claims to encode.
1414
+ *
1415
+ * @return string URL-safe base64.
1416
+ */
1417
+ private static function encode_after_success_payload( $claims ) {
1418
+ return rtrim( strtr( base64_encode( (string) wp_json_encode( $claims ) ), '+/', '-_' ), '=' ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
1419
+ }
1420
+
1421
+ /**
1422
+ * Decode token claims.
1423
+ *
1424
+ * @param string $payload URL-safe base64.
1425
+ *
1426
+ * @return array The claims, or an empty array if the payload is unreadable.
1427
+ */
1428
+ private static function decode_after_success_payload( $payload ) {
1429
+ $json = base64_decode( strtr( $payload, '-_', '+/' ), true ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
1430
+
1431
+ if ( false === $json ) {
1432
+ return [];
1433
+ }
1434
+
1435
+ $claims = json_decode( $json, true );
1436
+
1437
+ return is_array( $claims ) ? $claims : [];
1438
+ }
1439
+
1201
1440
  /**
1202
1441
  * Reduce a post-checkout destination to one this site is willing to send readers to.
1203
1442
  *
1204
1443
  * The destination reaches the thank-you page through the request, whether it came from
1205
1444
  * the block's own settings or from the link the reader followed, and by that point the
1206
- * two are indistinguishable. Core's redirect validation decides, so the destinations
1207
- * this site accepts are the ones `allowed_redirect_hosts` reports. That's this site's
1208
- * own host, plus whatever a publisher adds through that filter, plus anything another
1209
- * plugin has added (`Newspack\NRH` registers one).
1445
+ * two look alike. A signature tells them apart: one is minted when a block renders a
1446
+ * destination a publisher configured, so a destination carrying a valid one is this
1447
+ * site's own and is honoured wherever it points.
1210
1448
  *
1211
- * @param string $url The requested destination.
1449
+ * Everything else falls to core's redirect validation, which accepts what
1450
+ * `allowed_redirect_hosts` reports — this site's own host, plus whatever a publisher
1451
+ * adds through that filter, plus anything another plugin has added (`Newspack\NRH`
1452
+ * registers one). A destination arriving in a link with no signature has to clear that
1453
+ * bar, which is what keeps a crafted link from choosing where a reader lands.
1454
+ *
1455
+ * @param string $url The requested destination.
1456
+ * @param string $token Token offered with the request, if any.
1212
1457
  *
1213
1458
  * @return string The destination, or an empty string if it is not allowed.
1214
1459
  */
1215
- public static function sanitize_after_success_url( $url ) {
1216
- $url = sanitize_url( (string) $url );
1460
+ public static function sanitize_after_success_url( $url, $token = '' ) {
1461
+ // A token carries its own destination, so a mutated `after_success_url` alongside it
1462
+ // is ignored rather than compared against.
1463
+ $vouched = self::parse_after_success_token( $token );
1464
+
1465
+ if ( '' !== $vouched ) {
1466
+ // Returned as verified. `wp_sanitize_redirect()` is deliberately not applied to
1467
+ // this branch: it strips `'` and percent-encodes non-ASCII, so it would rewrite a
1468
+ // destination this site has already established is the publisher's own — the same
1469
+ // drift the token exists to prevent. The untrusted branch below still gets it, via
1470
+ // `wp_validate_redirect()`. Both have been through `sanitize_url()` in normalising.
1471
+ return $vouched;
1472
+ }
1473
+
1474
+ $url = self::normalize_after_success_url( $url );
1217
1475
 
1218
1476
  if ( empty( $url ) ) {
1219
1477
  return '';
1220
1478
  }
1221
1479
 
1222
- // Core compares hosts case-sensitively; host names aren't. Normalise first so this
1223
- // site's own host typed in capitals isn't read as somewhere else.
1224
- $host = wp_parse_url( $url, PHP_URL_HOST );
1225
- if ( $host && strtolower( $host ) !== $host ) {
1226
- $url = str_replace( '://' . $host, '://' . strtolower( $host ), $url );
1480
+ $validated = (string) wp_validate_redirect( $url, '' );
1481
+
1482
+ if ( '' === $validated ) {
1483
+ /**
1484
+ * Fires when a post-checkout destination is refused.
1485
+ *
1486
+ * The reader is sent nowhere and the modal simply closes, which looks the same
1487
+ * as a publisher not configuring a destination at all. This is the hook to
1488
+ * watch if you need to tell those two apart.
1489
+ *
1490
+ * @param string $url The refused destination.
1491
+ */
1492
+ do_action( 'newspack_blocks_modal_checkout_after_success_url_rejected', $url );
1227
1493
  }
1228
1494
 
1229
- return (string) wp_validate_redirect( $url, '' );
1495
+ return $validated;
1230
1496
  }
1231
1497
 
1232
1498
  /**
@@ -1255,7 +1521,8 @@ final class Modal_Checkout {
1255
1521
  unset(
1256
1522
  $params['after_success_behavior'],
1257
1523
  $params['after_success_url'],
1258
- $params['after_success_button_label']
1524
+ $params['after_success_button_label'],
1525
+ $params['after_success_token']
1259
1526
  );
1260
1527
  }
1261
1528
 
@@ -1275,11 +1542,14 @@ final class Modal_Checkout {
1275
1542
  \wp_parse_str( $referrer_query, $request_params );
1276
1543
  }
1277
1544
  }
1545
+ $token = isset( $request_params['after_success_token'] ) ? sanitize_text_field( wp_unslash( $request_params['after_success_token'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1546
+
1278
1547
  $params = array_filter(
1279
1548
  [
1280
1549
  'after_success_behavior' => isset( $request_params['after_success_behavior'] ) ? sanitize_text_field( wp_unslash( $request_params['after_success_behavior'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1281
- 'after_success_url' => isset( $request_params['after_success_url'] ) ? self::sanitize_after_success_url( wp_unslash( $request_params['after_success_url'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1550
+ 'after_success_url' => isset( $request_params['after_success_url'] ) ? self::sanitize_after_success_url( wp_unslash( $request_params['after_success_url'] ), $token ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1282
1551
  'after_success_button_label' => isset( $request_params['after_success_button_label'] ) ? sanitize_text_field( wp_unslash( $request_params['after_success_button_label'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1552
+ 'after_success_token' => $token,
1283
1553
  'action_type' => isset( $request_params['action_type'] ) ? sanitize_text_field( wp_unslash( $request_params['action_type'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1284
1554
  ]
1285
1555
  );
@@ -7,7 +7,7 @@
7
7
  * Author URI: https://newspack.com/
8
8
  * Text Domain: newspack-blocks
9
9
  * Domain Path: /languages
10
- * Version: 4.28.1-hotfix-blocks-input-validation.2
10
+ * Version: 4.28.1-hotfix-blocks-input-validation.4
11
11
  *
12
12
  * @package Newspack_Blocks
13
13
  */
@@ -15,7 +15,7 @@
15
15
  define( 'NEWSPACK_BLOCKS__PLUGIN_FILE', __FILE__ );
16
16
  define( 'NEWSPACK_BLOCKS__BLOCKS_DIRECTORY', 'dist/' );
17
17
  define( 'NEWSPACK_BLOCKS__PLUGIN_DIR', plugin_dir_path( NEWSPACK_BLOCKS__PLUGIN_FILE ) );
18
- define( 'NEWSPACK_BLOCKS__VERSION', '4.28.1-hotfix-blocks-input-validation.2' );
18
+ define( 'NEWSPACK_BLOCKS__VERSION', '4.28.1-hotfix-blocks-input-validation.4' );
19
19
 
20
20
  require_once NEWSPACK_BLOCKS__PLUGIN_DIR . 'includes/class-newspack-blocks.php';
21
21
  require_once NEWSPACK_BLOCKS__PLUGIN_DIR . 'includes/class-newspack-blocks-api.php';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/newspack-blocks",
3
- "version": "4.28.1-hotfix-blocks-input-validation.2",
3
+ "version": "4.28.1-hotfix-blocks-input-validation.4",
4
4
  "author": "Automattic",
5
5
  "description": "=== Newspack Blocks === Contributors: (this should be a list of wordpress.org userid's) Donate link: https://example.com/ Tags: comments, spam Requires at least: 4.5 Tested up to: 5.1.1 Stable tag: 0.1.0 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html",
6
6
  "repository": {
@@ -113,6 +113,10 @@ function render_callback( $attributes ) {
113
113
  $hidden_fields .= $after_success_behavior ? '<input type="hidden" name="after_success_behavior" value="' . esc_attr( $after_success_behavior ) . '" />' : '';
114
114
  $hidden_fields .= $after_success_button_label ? '<input type="hidden" name="after_success_button_label" value="' . esc_attr( $after_success_button_label ) . '" />' : '';
115
115
  $hidden_fields .= $after_success_url ? '<input type="hidden" name="after_success_url" value="' . esc_attr( $after_success_url ) . '" />' : '';
116
+ // Vouched for here because this is the last point the destination is known to come
117
+ // from the block's own settings rather than from the request.
118
+ $after_success_token = $after_success_url ? Modal_Checkout::get_after_success_token( $after_success_url ) : '';
119
+ $hidden_fields .= $after_success_token ? '<input type="hidden" name="after_success_token" value="' . esc_attr( $after_success_token ) . '" />' : '';
116
120
  }
117
121
 
118
122
  ob_start();
@@ -212,6 +212,16 @@ abstract class Newspack_Blocks_Donate_Renderer_Base {
212
212
  <input type='hidden' name='<?php echo esc_attr( $param_name ); ?>' value='<?php echo esc_attr( $value ); ?>' />
213
213
  <?php
214
214
  }
215
+
216
+ // Vouched for here because this is the last point the destination is known to come
217
+ // from the block's own settings rather than from the request.
218
+ $after_success_url = isset( $attributes['afterSuccessURL'] ) ? $attributes['afterSuccessURL'] : '';
219
+ $after_success_token = $after_success_url ? \Newspack_Blocks\Modal_Checkout::get_after_success_token( $after_success_url ) : '';
220
+ if ( $after_success_token ) {
221
+ ?>
222
+ <input type='hidden' name='after_success_token' value='<?php echo esc_attr( $after_success_token ); ?>' />
223
+ <?php
224
+ }
215
225
  }
216
226
  return ob_get_clean();
217
227
  }
@@ -104,6 +104,7 @@ export const PICKER_CONTEXT_FIELDS = [
104
104
  'after_success_behavior',
105
105
  'after_success_url',
106
106
  'after_success_button_label',
107
+ 'after_success_token',
107
108
  'gate_post_id',
108
109
  'newspack_popup_id',
109
110
  'prompt_title',
@@ -24,7 +24,7 @@ import {
24
24
  getCheckoutData,
25
25
  getFormattedAmount,
26
26
  } from './utils';
27
- import { resolveCheckoutButtonForm, readCheckoutData } from './checkout-button-trigger';
27
+ import { resolveCheckoutButtonForm, readCheckoutData, PICKER_CONTEXT_FIELDS } from './checkout-button-trigger';
28
28
  import { applyCtaAttribution } from '../shared/js/cta-attribution';
29
29
 
30
30
  const CLASS_PREFIX = newspackBlocksModal.newspack_class_prefix;
@@ -369,15 +369,10 @@ domReady( () => {
369
369
  const variationModal = [ ...variationModals ].find( modal => modal.dataset.productId === checkoutData.product_id );
370
370
  if ( variationModal ) {
371
371
  variationModal.querySelectorAll( `form[target="${ IFRAME_NAME }"]` ).forEach( singleVariationForm => {
372
- // Fill in the hidden params in the variation modal.
373
- [
374
- 'after_success_behavior',
375
- 'after_success_url',
376
- 'after_success_button_label',
377
- 'gate_post_id',
378
- 'newspack_popup_id',
379
- 'prompt_title',
380
- ].forEach( hiddenParam => {
372
+ // Fill in the hidden params in the variation modal. Shares one list with
373
+ // copyContextFields() so the two cannot drift: a field missing here is a
374
+ // field the variation path silently drops.
375
+ PICKER_CONTEXT_FIELDS.forEach( hiddenParam => {
381
376
  const existingInputs = singleVariationForm.querySelectorAll( 'input[name="' + hiddenParam + '"]' );
382
377
  if ( 0 === existingInputs.length ) {
383
378
  singleVariationForm.prepend( createHiddenInput( hiddenParam, checkoutData[ hiddenParam ] ) );
@@ -47,7 +47,10 @@ if ( ! $is_valid ) {
47
47
 
48
48
  $is_success = ! $order->has_status( 'failed' );
49
49
  $after_success_behavior = isset( $_GET['after_success_behavior'] ) ? \sanitize_text_field( \wp_unslash( $_GET['after_success_behavior'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
50
- $after_success_url = isset( $_GET['after_success_url'] ) ? esc_url( \Newspack_Blocks\Modal_Checkout::sanitize_after_success_url( \sanitize_url( \wp_unslash( $_GET['after_success_url'] ) ) ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
50
+ $after_success_token = isset( $_GET['after_success_token'] ) ? \sanitize_text_field( \wp_unslash( $_GET['after_success_token'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
51
+ // Not escaped here: the value is escaped where it is output, and escaping it into the
52
+ // variable would leave it holding something other than the destination that was verified.
53
+ $after_success_url = isset( $_GET['after_success_url'] ) ? \Newspack_Blocks\Modal_Checkout::sanitize_after_success_url( \sanitize_url( \wp_unslash( $_GET['after_success_url'] ) ), $after_success_token ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
51
54
  $after_success_label = isset( $_GET['after_success_button_label'] ) ? \sanitize_text_field( \wp_unslash( $_GET['after_success_button_label'] ) ) : \Newspack_Blocks\Modal_Checkout::get_modal_checkout_labels( 'after_success' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
52
55
  $checkout_data = Checkout_Data::get_checkout_data( $order );
53
56
 
@@ -3,7 +3,7 @@
3
3
  'name' => 'automattic/newspack-blocks',
4
4
  'pretty_version' => 'dev-main',
5
5
  'version' => 'dev-main',
6
- 'reference' => '12e6bd898d28eaf4fb6a59633f99b297febc308f',
6
+ 'reference' => 'cadf9db7f24b87094470dcebc368c87e8f5cda36',
7
7
  'type' => 'wordpress-plugin',
8
8
  'install_path' => __DIR__ . '/../../',
9
9
  'aliases' => array(),
@@ -13,7 +13,7 @@
13
13
  'automattic/newspack-blocks' => array(
14
14
  'pretty_version' => 'dev-main',
15
15
  'version' => 'dev-main',
16
- 'reference' => '12e6bd898d28eaf4fb6a59633f99b297febc308f',
16
+ 'reference' => 'cadf9db7f24b87094470dcebc368c87e8f5cda36',
17
17
  'type' => 'wordpress-plugin',
18
18
  'install_path' => __DIR__ . '/../../',
19
19
  'aliases' => array(),