11import * as voprf from '../crypto/voprf' ;
22
3- import { Provider , EarnedTokenCookie , Callbacks , QUALIFIED_HOSTNAMES , QUALIFIED_PATHNAMES , QUALIFIED_PARAMS , isIssuingHostname , isQualifiedPathname , areQualifiedQueryParams , areQualifiedBodyFormParams } from './provider' ;
3+ import { Provider , EarnedTokenCookie , Callbacks , QUALIFIED_HOSTNAMES , QUALIFIED_PATHNAMES , QUALIFIED_PARAMS , isIssuingHostname , isQualifiedPathname , areQualifiedQueryParams , areQualifiedBodyFormParams , getNormalizedFormData } from './provider' ;
44import { Storage } from '../storage' ;
55import Token from '../token' ;
66import axios from 'axios' ;
@@ -15,10 +15,10 @@ const COMMITMENT_URL: string =
1515 'https://raw.githubusercontent.com/privacypass/ec-commitments/master/commitments-p256.json' ;
1616
1717const ALL_ISSUING_CRITERIA : {
18- HOSTNAMES : QUALIFIED_HOSTNAMES ;
19- PATHNAMES : QUALIFIED_PATHNAMES ;
20- QUERY_PARAMS : QUALIFIED_PARAMS ;
21- BODY_PARAMS : QUALIFIED_PARAMS ;
18+ HOSTNAMES : QUALIFIED_HOSTNAMES | void ;
19+ PATHNAMES : QUALIFIED_PATHNAMES | void ;
20+ QUERY_PARAMS : QUALIFIED_PARAMS | void ;
21+ BODY_PARAMS : QUALIFIED_PARAMS | void ;
2222} = {
2323 HOSTNAMES : {
2424 exact : [ DEFAULT_ISSUING_HOSTNAME ] ,
@@ -28,17 +28,16 @@ const ALL_ISSUING_CRITERIA: {
2828 contains : [ '/checkcaptcha' ] ,
2929 } ,
3030 QUERY_PARAMS : {
31- some : [ 's=00000000-0000-0000-0000-000000000000' ] ,
31+ some : [ 's=00000000-0000-0000-0000-000000000000' ] ,
3232 } ,
33- BODY_PARAMS : {
34- }
33+ BODY_PARAMS : undefined ,
3534}
3635
3736const ALL_REDEMPTION_CRITERIA : {
38- HOSTNAMES : QUALIFIED_HOSTNAMES ;
39- PATHNAMES : QUALIFIED_PATHNAMES ;
40- QUERY_PARAMS : QUALIFIED_PARAMS ;
41- BODY_PARAMS : QUALIFIED_PARAMS ;
37+ HOSTNAMES : QUALIFIED_HOSTNAMES | void ;
38+ PATHNAMES : QUALIFIED_PATHNAMES | void ;
39+ QUERY_PARAMS : QUALIFIED_PARAMS | void ;
40+ BODY_PARAMS : QUALIFIED_PARAMS | void ;
4241} = {
4342 HOSTNAMES : {
4443 exact : [ DEFAULT_ISSUING_HOSTNAME ] ,
@@ -48,11 +47,11 @@ const ALL_REDEMPTION_CRITERIA: {
4847 contains : [ '/getcaptcha' ] ,
4948 } ,
5049 QUERY_PARAMS : {
51- some : [ 's!=00000000-0000-0000-0000-000000000000' ] ,
50+ some : [ 's!=00000000-0000-0000-0000-000000000000' ] ,
5251 } ,
5352 BODY_PARAMS : {
54- every : [ 'sitekey!=00000000-0000-0000-0000-000000000000' , 'motionData' , 'host!=www.hcaptcha.com' ] ,
55- }
53+ every : [ 'sitekey!=00000000-0000-0000-0000-000000000000' , 'motionData' , 'host!=www.hcaptcha.com' ] ,
54+ } ,
5655}
5756
5857const VERIFICATION_KEY : string = `-----BEGIN PUBLIC KEY-----
@@ -128,33 +127,23 @@ export class HcaptchaProvider extends Provider {
128127 handleBeforeRequest (
129128 details : chrome . webRequest . WebRequestBodyDetails ,
130129 ) : chrome . webRequest . BlockingResponse | void {
131- const url = new URL ( details . url ) ;
132- const formData : { [ key : string ] : string [ ] | string } = ( details . requestBody && details . requestBody . formData )
133- ? details . requestBody . formData
134- : { }
135- ;
136-
137- if ( this . matchesIssuingCriteria ( details , url , formData ) ) {
138- this . issueInfo = { requestId : details . requestId , url : details . url } ;
139130
131+ if ( this . matchesIssuingCriteria ( details ) ) {
140132 // do NOT cancel the request with captcha solution.
141133 return { cancel : false } ;
142134 }
143135
144- if ( this . matchesRedemptionCriteria ( details , url , formData ) ) {
145- this . redeemInfo = { requestId : details . requestId } ;
146-
136+ if ( this . matchesRedemptionCriteria ( details ) ) {
147137 // do NOT cancel the request to generate a new captcha.
148138 // note: "handleBeforeSendHeaders" will add request headers to embed a token.
149139 return { cancel : false } ;
150140 }
151141 }
152142
153143 private matchesIssuingCriteria (
154- details : chrome . webRequest . WebRequestBodyDetails ,
155- url : URL ,
156- formData : { [ key : string ] : string [ ] | string }
144+ details : chrome . webRequest . WebRequestBodyDetails ,
157145 ) : boolean {
146+
158147 // Only issue tokens for POST requests that contain data in body.
159148 if (
160149 ( details . method . toUpperCase ( ) !== 'POST' ) ||
@@ -164,6 +153,8 @@ export class HcaptchaProvider extends Provider {
164153 return false ;
165154 }
166155
156+ const url : URL = new URL ( details . url ) ;
157+
167158 // Only issue tokens to hosts belonging to the provider.
168159 if ( ! isIssuingHostname ( ALL_ISSUING_CRITERIA . HOSTNAMES , url ) ) {
169160 return false ;
@@ -179,19 +170,25 @@ export class HcaptchaProvider extends Provider {
179170 return false ;
180171 }
181172
182- // Only issue tokens when 'application/x-www-form-urlencoded' data parameters in POST body pass defined criteria.
183- if ( ! areQualifiedBodyFormParams ( ALL_ISSUING_CRITERIA . BODY_PARAMS , formData ) ) {
184- return false ;
173+ // conditionally short-circuit an expensive operation
174+ if ( ALL_ISSUING_CRITERIA . BODY_PARAMS !== undefined ) {
175+ const formData : { [ key : string ] : string [ ] | string } = getNormalizedFormData ( details ) ;
176+
177+ // Only issue tokens when 'application/x-www-form-urlencoded' or 'application/json' data parameters in POST body pass defined criteria.
178+ if ( ! areQualifiedBodyFormParams ( ALL_ISSUING_CRITERIA . BODY_PARAMS , formData ) ) {
179+ return false ;
180+ }
185181 }
186182
183+ this . issueInfo = { requestId : details . requestId , url : details . url } ;
184+
187185 return true ;
188186 }
189187
190188 private matchesRedemptionCriteria (
191- details : chrome . webRequest . WebRequestBodyDetails ,
192- url : URL ,
193- formData : { [ key : string ] : string [ ] | string }
189+ details : chrome . webRequest . WebRequestBodyDetails ,
194190 ) : boolean {
191+
195192 // Only redeem tokens for POST requests that contain data in body.
196193 if (
197194 ( details . method . toUpperCase ( ) !== 'POST' ) ||
@@ -201,6 +198,8 @@ export class HcaptchaProvider extends Provider {
201198 return false ;
202199 }
203200
201+ const url : URL = new URL ( details . url ) ;
202+
204203 // Only redeem tokens to hosts belonging to the provider.
205204 if ( ! isIssuingHostname ( ALL_REDEMPTION_CRITERIA . HOSTNAMES , url ) ) {
206205 return false ;
@@ -216,11 +215,18 @@ export class HcaptchaProvider extends Provider {
216215 return false ;
217216 }
218217
219- // Only redeem tokens when 'application/x-www-form-urlencoded' data parameters in POST body pass defined criteria.
220- if ( ! areQualifiedBodyFormParams ( ALL_REDEMPTION_CRITERIA . BODY_PARAMS , formData ) ) {
221- return false ;
218+ // conditionally short-circuit an expensive operation
219+ if ( ALL_REDEMPTION_CRITERIA . BODY_PARAMS !== undefined ) {
220+ const formData : { [ key : string ] : string [ ] | string } = getNormalizedFormData ( details ) ;
221+
222+ // Only redeem tokens when 'application/x-www-form-urlencoded' or 'application/json' data parameters in POST body pass defined criteria.
223+ if ( ! areQualifiedBodyFormParams ( ALL_REDEMPTION_CRITERIA . BODY_PARAMS , formData ) ) {
224+ return false ;
225+ }
222226 }
223227
228+ this . redeemInfo = { requestId : details . requestId } ;
229+
224230 return true ;
225231 }
226232
0 commit comments