nl_tokens: Parses the reCAPTCHA form and hands control over to the user
pl_tokens: function onCaptcha ( options , response , body ) { const callback = options . callback ; // UDF that has the responsibility of returning control back to cloudscraper const handler = options . onCaptcha ; // The form data to send back to Cloudflare const payload = { /* s, g-re-captcha-response */ } ; let cause ; let match ; match = body . match ( / <form(?: [^<>]*)? id=["']?challenge-form['"]?(?: [^<>]*)?>([\S\s]*?)<\/form> / ) ; if ( ! match ) { cause = 'Challenge form extraction failed' ; return callback ( new ParserError ( cause , options , response ) ) ; } // Defining response.challengeForm for debugging purposes const form = response . challengeForm = match [ 1 ] ; match = form . match ( / \/recaptcha\/api\/fallback\?k=([^\s"'<>]*) / ) ; if ( ! match ) { // The site key wasn't inside the form so search the entire document match = body . match ( / data-sitekey=["']?([^\s"'<>]*) / ) ; if ( ! match ) { cause = 'Unable to find the reCAPTCHA site key' ; return callback ( new ParserError ( cause , options , response ) ) ; } } // Everything that is needed to solve the reCAPTCHA response . captcha = { url : response . request . uri . href , siteKey : match [ 1 ] , form : payload } ; // Adding formData match = form . match ( / <input(?: [^<>]*)? name=[^<>]+> / g ) ; if ( ! match ) { cause = 'Challenge form is missing inputs' ; return callback ( new ParserError ( cause , options , response ) ) ; } const inputs = match ; // Only adding inputs that have both a name and value defined for ( let name , value , i = 0 ; i < inputs . length ; i ++ ) { name = inputs [ i ] . match ( / name=["']?([^\s"'<>]*) / ) ; if ( name ) { <mask> = inputs [ i ] . match ( / value=["']?([^\s"'<>]*) / ) ; if ( value ) { payload [ name [ 1 ] ] = value [ 1 ] ; } } } // Sanity check if ( ! payload [ 's' ] ) { cause = 'Challenge form is missing secret input' ; return callback ( new ParserError ( cause , options , response ) ) ; } // The callback used to green light form submission const submit = function ( error ) { if ( error ) { // Pass an user defined error back to the original request call return callback ( new CaptchaError ( error , options , response ) ) ; } onSubmitCaptcha ( options , response , body ) ; } ; // This seems like an okay-ish API (fewer arguments to the handler) response . captcha . submit = submit ; // We're handing control over to the user now. const thenable = handler ( options , response , body ) ; // Handle the case where the user returns a promise if ( thenable && typeof thenable . then === 'function' ) { // eslint-disable-next-line promise/catch-or-return thenable . then ( submit , function ( error ) { if ( ! error ) { // The user broke their promise with a falsy error submit ( new Error ( 'Falsy error' ) ) ; } else { submit ( error ) ; } } ) ; } }