@@ -228,17 +228,25 @@ function parseEncodedChallenge(value) {
228228 }
229229}
230230
231- function parsePaymentAuthenticate ( value ) {
232- if ( ! value || ! / ^ P a y m e n t \s + / i. test ( value ) ) return null
231+ function authenticateParams ( value , scheme ) {
232+ const header = String ( value ?? '' ) . replace ( / ^ w w w - a u t h e n t i c a t e : \s * / i, '' ) . trim ( )
233+ if ( ! header || ! new RegExp ( `^${ scheme } \\s+` , 'i' ) . test ( header ) ) return null
233234 const params = { }
234235 const pattern = / ( [ a - z A - Z ] [ \w - ] * ) = " ( [ ^ " ] * ) " / g
235- let match = pattern . exec ( value )
236+ let match = pattern . exec ( header )
236237
237238 while ( match ) {
238239 params [ match [ 1 ] ] = match [ 2 ]
239- match = pattern . exec ( value )
240+ match = pattern . exec ( header )
240241 }
241242
243+ return params
244+ }
245+
246+ function parsePaymentAuthenticate ( value ) {
247+ const params = authenticateParams ( value , 'Payment' )
248+ if ( ! params ) return null
249+
242250 const request = parseEncodedChallenge ( params . request )
243251 if ( ! request ) return null
244252
@@ -264,6 +272,19 @@ function parsePaymentAuthenticate(value) {
264272 }
265273}
266274
275+ function parseX402Authenticate ( value ) {
276+ const params = authenticateParams ( value , 'X402' )
277+ if ( ! params ) return null
278+
279+ const requirements = parseEncodedChallenge ( params . requirements ?? params . request )
280+ if ( ! requirements || ! Array . isArray ( requirements . accepts ) ) return null
281+
282+ return {
283+ protocol : requirements . protocol ?? 'x402' ,
284+ ...requirements ,
285+ }
286+ }
287+
267288async function fetchDocument ( url ) {
268289 const response = await fetch ( url , {
269290 headers : {
@@ -296,16 +317,18 @@ async function probeEndpoint(entry) {
296317 const headerChallenge = parseEncodedChallenge (
297318 response . headers . get ( 'payment-required' ) ?? response . headers . get ( 'x-payment-required' ) ,
298319 )
299- const paymentChallenge = parsePaymentAuthenticate ( response . headers . get ( 'www-authenticate' ) )
320+ const authenticateChallenge = parsePaymentAuthenticate ( response . headers . get ( 'www-authenticate' ) )
321+ ?? parseX402Authenticate ( response . headers . get ( 'www-authenticate' ) )
300322
301323 if ( ! body . json ?. accepts ?. length ) {
302324 if ( headerChallenge ) {
303325 body . json = headerChallenge
304326 }
305- else if ( paymentChallenge ) {
306- paymentChallenge . resource . url = entry . url
307- paymentChallenge . accepts [ 0 ] . resource = entry . url
308- body . json = paymentChallenge
327+ else if ( authenticateChallenge ) {
328+ authenticateChallenge . resource = authenticateChallenge . resource ?? { url : entry . url }
329+ authenticateChallenge . resource . url = authenticateChallenge . resource . url || entry . url
330+ authenticateChallenge . accepts [ 0 ] . resource = authenticateChallenge . accepts [ 0 ] . resource || entry . url
331+ body . json = authenticateChallenge
309332 }
310333 }
311334
0 commit comments