@@ -14,6 +14,14 @@ window.NeuriteEnv = {
1414 if ( this . isProd ) return 'https://neurite.network' ;
1515 if ( this . isTest ) return 'https://test.neurite.network' ;
1616 return null ; // Electron-local and dev-hosted must proxy
17+ } ,
18+
19+ isTrustedMessageOrigin ( origin ) {
20+ return (
21+ origin === 'https://neurite.network' ||
22+ origin === 'https://test.neurite.network' ||
23+ ( this . isElectron && ( origin === 'null' || origin . startsWith ( 'http://localhost' ) ) )
24+ ) ;
1725 }
1826}
1927
@@ -45,7 +53,7 @@ class NeuriteBackend {
4553 } ,
4654 ...options
4755 } ;
48-
56+
4957 try {
5058 const response = window . NeuriteEnv . isElectronWithLocalFrontend
5159 ? await this . #electronRequest( endpoint , requestOptions , isStreaming )
@@ -75,25 +83,42 @@ class NeuriteBackend {
7583 if ( handleUnauthorized ) return response ;
7684 return handleNeuriteUnauthorized ( ) ;
7785 }
78-
7986 return response ;
8087 }
8188
8289 async #electronRequest( endpoint , requestOptions , isStreaming ) {
90+ const fullEndpoint = `/api${ endpoint } ` ;
91+ const encoder = new TextEncoder ( ) ;
92+
8393 if ( isStreaming ) {
8494 const id = crypto . randomUUID ( ) ;
85- const encoder = new TextEncoder ( ) ;
86-
95+
96+ let responseHeaders = { } ;
97+ let status = 200 ;
98+ let statusText = '' ;
99+
87100 const stream = new ReadableStream ( {
88101 start ( controller ) {
89102 const onChunk = ( event , data ) => {
90103 if ( data . id !== id ) return ;
91-
92- if ( data . chunk ) controller . enqueue ( encoder . encode ( data . chunk ) ) ;
104+
105+ if ( data . streamMeta ) {
106+ // Initial headers/status block
107+ responseHeaders = data . streamMeta . headers || { } ;
108+ status = data . streamMeta . status || 200 ;
109+ statusText = data . streamMeta . statusText || '' ;
110+ return ;
111+ }
112+
113+ if ( data . chunk ) {
114+ controller . enqueue ( encoder . encode ( data . chunk ) ) ;
115+ }
116+
93117 if ( data . done ) {
94118 controller . close ( ) ;
95119 window . electronAPI . _removeStreamListener ( onChunk ) ;
96120 }
121+
97122 if ( data . error ) {
98123 controller . error ( new Error ( data . error ) ) ;
99124 window . electronAPI . _removeStreamListener ( onChunk ) ;
@@ -102,26 +127,37 @@ class NeuriteBackend {
102127 window . electronAPI . _addStreamListener ( onChunk ) ;
103128 }
104129 } ) ;
105-
106- window . electronAPI . sendStreamRequest ( id , `/api ${ endpoint } ` , requestOptions ) ;
107-
130+
131+ window . electronAPI . sendStreamRequest ( id , fullEndpoint , requestOptions ) ;
132+
108133 return new Response ( stream , {
109- headers : { 'Content-Type' : 'application/json' }
134+ headers : new Headers ( responseHeaders ) ,
135+ status,
136+ statusText
110137 } ) ;
111138 }
112-
113- const response = await window . electronAPI . secureFetch ( endpoint , requestOptions ) ;
114- return {
115- ok : response . ok ,
116- status : response . status ,
117- json : async ( ) => response . data
118- } ;
139+
140+ // --- Non-streaming ---
141+ const raw = await window . electronAPI . secureFetch ( fullEndpoint , requestOptions ) ;
142+
143+ const headers = new Headers ( raw . headers || { } ) ;
144+ const body = raw . isText
145+ ? raw . body
146+ : new Uint8Array ( raw . body ) ; // proxy.html sends byte array if not text
147+
148+ return new Response (
149+ raw . isText ? body : body . buffer ,
150+ {
151+ status : raw . status ,
152+ statusText : raw . statusText || '' ,
153+ headers
154+ }
155+ ) ;
119156 }
120157}
121158
122159window . NeuriteBackend = new NeuriteBackend ( ) ;
123160
124-
125161// neuritePanel.js
126162
127163class NeuritePanel {
@@ -347,9 +383,27 @@ class BalanceHandler {
347383 }
348384
349385 try {
350- const paymentTab = window . open ( 'about:blank' , '_blank' , 'width=500,height=600' ) ;
351386 const sessionId = await this . createCheckoutSession ( roundedAmount ) ;
352- this . initPaymentTab ( paymentTab , sessionId ) ;
387+ const keys = await updatePublicKeys ( ) ;
388+ const stripePublicKey = keys . stripePublicKey ;
389+
390+ if ( ! stripePublicKey ) throw new Error ( 'Stripe public key not available' ) ;
391+
392+ const redirectPage = window . NeuriteEnv . isTest
393+ ? 'https://test.neurite.network/resources/striperedirect.html'
394+ : 'https://neurite.network/resources/striperedirect.html' ;
395+
396+ const origin = window . location . origin ;
397+ const stripeRedirectUrl = `${ redirectPage } ?sessionId=${ encodeURIComponent ( sessionId ) } &pk=${ encodeURIComponent ( stripePublicKey ) } &origin=${ encodeURIComponent ( origin ) } ` ;
398+
399+ if ( window . NeuriteEnv . isElectronWithLocalFrontend ) {
400+ window . electronAPI . openPopupViaProxy ( stripeRedirectUrl ) ;
401+ } else {
402+ const popup = window . open ( stripeRedirectUrl , 'StripePayment' , 'width=500,height=600' ) ;
403+ if ( ! popup ) {
404+ alert ( "Please enable popups for this site to complete the payment." ) ;
405+ }
406+ }
353407 } catch ( error ) {
354408 // Error handling
355409 if ( error . message . includes ( 'Exceeds maximum balance' ) ) {
@@ -361,35 +415,6 @@ class BalanceHandler {
361415 }
362416 }
363417
364- // Method within your class to initialize the payment tab and load Stripe.js
365- initPaymentTab ( paymentTab , sessionId ) {
366- paymentTab . document . body . innerHTML = '<p>Redirecting to payment...</p>' ;
367- const stripeScript = paymentTab . document . createElement ( 'script' ) ;
368- stripeScript . src = 'https://js.stripe.com/v3/' ;
369-
370- stripeScript . onload = async ( ) => {
371- // Retrieve the Stripe key
372- const keys = await updatePublicKeys ( ) ;
373- const stripePublicKey = keys . stripePublicKey ;
374-
375- if ( stripePublicKey ) {
376- // Create and inject a script to initiate Stripe with the session ID
377- const redirectScript = `
378- const stripe = Stripe('${ stripePublicKey } ');
379- stripe.redirectToCheckout({ sessionId: '${ sessionId } ' }).catch((error) => {
380- document.body.innerHTML = 'Error: ' + error.message;
381- });
382- ` ;
383- const scriptTag = paymentTab . document . createElement ( 'script' ) ;
384- scriptTag . text = redirectScript ;
385- paymentTab . document . body . appendChild ( scriptTag ) ;
386- }
387- } ;
388-
389- // Append Stripe.js to the payment tab
390- paymentTab . document . head . appendChild ( stripeScript ) ;
391- }
392-
393418 // Fetch the user's balance directly from the Stripe Worker
394419 async fetchUserBalance ( ) {
395420 try {
0 commit comments