@@ -63,20 +63,8 @@ export class ReCaptchaV3Provider implements AppCheckProvider {
63
63
* @internal
64
64
*/
65
65
async getToken ( ) : Promise < AppCheckTokenInternal > {
66
- if ( this . _throttleData ) {
67
- if ( Date . now ( ) - this . _throttleData . allowRequestsAfter > 0 ) {
68
- // If after throttle timestamp, clear throttle data.
69
- this . _throttleData = null ;
70
- } else {
71
- // If before, throw.
72
- throw ERROR_FACTORY . create ( AppCheckError . THROTTLED , {
73
- time : new Date (
74
- this . _throttleData . allowRequestsAfter
75
- ) . toLocaleString ( ) ,
76
- httpStatus : this . _throttleData . httpStatus
77
- } ) ;
78
- }
79
- }
66
+ throwIfThrottled ( this . _throttleData ) ;
67
+
80
68
if ( ! this . _app || ! this . _platformLoggerProvider ) {
81
69
// This should only occur if user has not called initializeAppCheck().
82
70
// We don't have an appName to provide if so.
@@ -101,61 +89,25 @@ export class ReCaptchaV3Provider implements AppCheckProvider {
101
89
) ;
102
90
} catch ( e ) {
103
91
if ( ( e as FirebaseError ) . code === AppCheckError . FETCH_STATUS_ERROR ) {
104
- const throttleData = this . _setBackoff (
105
- Number ( ( e as FirebaseError ) . customData ?. httpStatus )
92
+ this . _throttleData = setBackoff (
93
+ Number ( ( e as FirebaseError ) . customData ?. httpStatus ) ,
94
+ this . _throttleData
106
95
) ;
107
96
throw ERROR_FACTORY . create ( AppCheckError . THROTTLED , {
108
- time : getDurationString ( throttleData . allowRequestsAfter - Date . now ( ) ) ,
109
- httpStatus : throttleData . httpStatus
97
+ time : getDurationString (
98
+ this . _throttleData . allowRequestsAfter - Date . now ( )
99
+ ) ,
100
+ httpStatus : this . _throttleData . httpStatus
110
101
} ) ;
111
102
} else {
112
103
throw e ;
113
104
}
114
105
}
106
+ // If successful, clear throttle data.
107
+ this . _throttleData = null ;
115
108
return result ;
116
109
}
117
110
118
- /**
119
- * Set throttle data to block requests until after a certain time
120
- * depending on the failed request's status code.
121
- * @param httpStatus - Status code of failed request.
122
- * @returns Data about current throttle state and expiration time.
123
- */
124
- private _setBackoff ( httpStatus : number ) : ThrottleData {
125
- /**
126
- * Block retries for 1 day for the following error codes:
127
- *
128
- * 404: Likely malformed URL.
129
- *
130
- * 403:
131
- * - Attestation failed
132
- * - Wrong API key
133
- * - Project deleted
134
- */
135
- if ( httpStatus === 404 || httpStatus === 403 ) {
136
- this . _throttleData = {
137
- backoffCount : 1 ,
138
- allowRequestsAfter : Date . now ( ) + ONE_DAY ,
139
- httpStatus
140
- } ;
141
- } else {
142
- /**
143
- * For all other error codes, the time when it is ok to retry again
144
- * is based on exponential backoff.
145
- */
146
- const backoffCount = this . _throttleData
147
- ? this . _throttleData . backoffCount
148
- : 0 ;
149
- const backoffMillis = calculateBackoffMillis ( backoffCount , 1000 , 2 ) ;
150
- this . _throttleData = {
151
- backoffCount : backoffCount + 1 ,
152
- allowRequestsAfter : Date . now ( ) + backoffMillis ,
153
- httpStatus
154
- } ;
155
- }
156
- return this . _throttleData ;
157
- }
158
-
159
111
/**
160
112
* @internal
161
113
*/
@@ -290,3 +242,56 @@ export class CustomProvider implements AppCheckProvider {
290
242
}
291
243
}
292
244
}
245
+
246
+ /**
247
+ * Set throttle data to block requests until after a certain time
248
+ * depending on the failed request's status code.
249
+ * @param httpStatus - Status code of failed request.
250
+ * @returns Data about current throttle state and expiration time.
251
+ */
252
+ function setBackoff (
253
+ httpStatus : number ,
254
+ throttleData : ThrottleData | null
255
+ ) : ThrottleData {
256
+ /**
257
+ * Block retries for 1 day for the following error codes:
258
+ *
259
+ * 404: Likely malformed URL.
260
+ *
261
+ * 403:
262
+ * - Attestation failed
263
+ * - Wrong API key
264
+ * - Project deleted
265
+ */
266
+ if ( httpStatus === 404 || httpStatus === 403 ) {
267
+ return {
268
+ backoffCount : 1 ,
269
+ allowRequestsAfter : Date . now ( ) + ONE_DAY ,
270
+ httpStatus
271
+ } ;
272
+ } else {
273
+ /**
274
+ * For all other error codes, the time when it is ok to retry again
275
+ * is based on exponential backoff.
276
+ */
277
+ const backoffCount = throttleData ? throttleData . backoffCount : 0 ;
278
+ const backoffMillis = calculateBackoffMillis ( backoffCount , 1000 , 2 ) ;
279
+ return {
280
+ backoffCount : backoffCount + 1 ,
281
+ allowRequestsAfter : Date . now ( ) + backoffMillis ,
282
+ httpStatus
283
+ } ;
284
+ }
285
+ }
286
+
287
+ function throwIfThrottled ( throttleData : ThrottleData | null ) : void {
288
+ if ( throttleData ) {
289
+ if ( Date . now ( ) - throttleData . allowRequestsAfter <= 0 ) {
290
+ // If before, throw.
291
+ throw ERROR_FACTORY . create ( AppCheckError . THROTTLED , {
292
+ time : getDurationString ( throttleData . allowRequestsAfter - Date . now ( ) ) ,
293
+ httpStatus : throttleData . httpStatus
294
+ } ) ;
295
+ }
296
+ }
297
+ }
0 commit comments