1/** 2 * PayPal request fetch interceptor for Woo Fraud Protection. 3 * 4 * Injects the browser session into supported PayPal requests. Errors 5 * remain fail open and never prevent the original Fetch call. 6 */ 7( function () { 8 if ( ! window.wcFraudProtection ) { 9 return; 10 } 11 12 const originalFetch = window.fetch; 13 const protectedPayPalEndpoints = [ 14 'ppc-create-order', 15 'ppc-create-setup-token', 16 'ppc-vault-create-order', 17 ]; 18 let resetBeforeNextPayPalRequest = false; 19 20 function getEndpoint( resource ) { 21 const url = 22 resource instanceof Request ? resource.url : String( resource ); 23 return ( 24 new URL( url, window.location.href ).searchParams.get( 25 'wc-ajax' 26 ) || '' 27 ); 28 } 29 30 function resetSession( fp ) { 31 try { 32 if ( typeof fp.reset === 'function' ) { 33 fp.reset(); 34 } 35 } catch { 36 // Fail open. 37 } 38 } 39 40 async function classifyResponse( response ) { 41 if ( ! response || false === response.ok ) { 42 return 'failure'; 43 } 44 45 try { 46 const data = await response.clone().json(); 47 return data && false === data.success ? 'failure' : 'success'; 48 } catch { 49 return 'unknown'; 50 } 51 } 52 53 async function dispatchProtectedPayPalRequest( 54 thisArg, 55 fp, 56 resource, 57 init 58 ) { 59 if ( resetBeforeNextPayPalRequest ) { 60 resetSession( fp ); 61 resetBeforeNextPayPalRequest = false; 62 } 63 64 try { 65 const sessionId = await fp.acquireSessionId(); 66 const body = JSON.parse( init.body ); 67 body[ fp.config.sessionIdField ] = sessionId; 68 init.body = JSON.stringify( body ); 69 } catch { 70 // Fail open with the original request data. 71 } 72 73 let response; 74 try { 75 response = await originalFetch.call( thisArg, resource, init ); 76 } catch ( e ) { 77 resetSession( fp ); 78 throw e; 79 } 80 81 const result = await classifyResponse( response ); 82 if ( 'failure' === result ) { 83 resetSession( fp ); 84 } else { 85 resetBeforeNextPayPalRequest = true; 86 } 87 88 return response; 89 } 90 91 window.fetch = function ( resource, init ) { 92 try { 93 const fp = window.wcFraudProtection; 94 if ( 95 protectedPayPalEndpoints.includes( getEndpoint( resource ) ) && 96 fp && 97 typeof fp.acquireSessionId === 'function' 98 ) { 99 return dispatchProtectedPayPalRequest( 100 this, 101 fp, 102 resource, 103 init || {} 104 ); 105 } 106 } catch { 107 // Fail open. 108 } 109 110 return originalFetch.call( this, resource, init ); 111 }; 112} )();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.