@firebase/app-check 0.5.1 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/app-check-public.d.ts +10 -0
- package/dist/app-check.d.ts +10 -0
- package/dist/esm/index.esm.js +267 -89
- package/dist/esm/index.esm.js.map +1 -1
- package/dist/esm/index.esm2017.js +217 -47
- package/dist/esm/index.esm2017.js.map +1 -1
- package/dist/esm/src/constants.d.ts +4 -0
- package/dist/esm/src/errors.d.ts +6 -1
- package/dist/esm/src/internal-api.d.ts +1 -0
- package/dist/esm/src/providers.d.ts +10 -0
- package/dist/esm/src/providers.test.d.ts +17 -0
- package/dist/esm/src/state.d.ts +1 -0
- package/dist/esm/src/types.d.ts +5 -0
- package/dist/esm/src/util.d.ts +1 -0
- package/dist/index.cjs.js +266 -88
- package/dist/index.cjs.js.map +1 -1
- package/dist/src/constants.d.ts +4 -0
- package/dist/src/errors.d.ts +6 -1
- package/dist/src/internal-api.d.ts +1 -0
- package/dist/src/providers.d.ts +10 -0
- package/dist/src/providers.test.d.ts +17 -0
- package/dist/src/state.d.ts +1 -0
- package/dist/src/types.d.ts +5 -0
- package/dist/src/util.d.ts +1 -0
- package/package.json +2 -2
package/dist/index.cjs.js
CHANGED
|
@@ -78,7 +78,11 @@ var TOKEN_REFRESH_TIME = {
|
|
|
78
78
|
* This is the maximum retrial wait, currently 16 minutes.
|
|
79
79
|
*/
|
|
80
80
|
RETRIAL_MAX_WAIT: 16 * 60 * 1000
|
|
81
|
-
};
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* One day in millis, for certain error code backoffs.
|
|
84
|
+
*/
|
|
85
|
+
var ONE_DAY = 24 * 60 * 60 * 1000;
|
|
82
86
|
|
|
83
87
|
/**
|
|
84
88
|
* @license
|
|
@@ -242,6 +246,7 @@ var ERRORS = (_a = {},
|
|
|
242
246
|
_a["storage-get" /* STORAGE_GET */] = 'Error thrown when reading from storage. Original error: {$originalErrorMessage}.',
|
|
243
247
|
_a["storage-set" /* STORAGE_WRITE */] = 'Error thrown when writing to storage. Original error: {$originalErrorMessage}.',
|
|
244
248
|
_a["recaptcha-error" /* RECAPTCHA_ERROR */] = 'ReCAPTCHA error.',
|
|
249
|
+
_a["throttled" /* THROTTLED */] = "Requests throttled due to {$httpStatus} error. Attempts allowed again after {$time}",
|
|
245
250
|
_a);
|
|
246
251
|
var ERROR_FACTORY = new util.ErrorFactory('appCheck', 'AppCheck', ERRORS);
|
|
247
252
|
|
|
@@ -284,6 +289,28 @@ function uuidv4() {
|
|
|
284
289
|
var r = (Math.random() * 16) | 0, v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
285
290
|
return v.toString(16);
|
|
286
291
|
});
|
|
292
|
+
}
|
|
293
|
+
function getDurationString(durationInMillis) {
|
|
294
|
+
var totalSeconds = Math.round(durationInMillis / 1000);
|
|
295
|
+
var days = Math.floor(totalSeconds / (3600 * 24));
|
|
296
|
+
var hours = Math.floor((totalSeconds - days * 3600 * 24) / 3600);
|
|
297
|
+
var minutes = Math.floor((totalSeconds - days * 3600 * 24 - hours * 3600) / 60);
|
|
298
|
+
var seconds = totalSeconds - days * 3600 * 24 - hours * 3600 - minutes * 60;
|
|
299
|
+
var result = '';
|
|
300
|
+
if (days) {
|
|
301
|
+
result += pad(days) + 'd:';
|
|
302
|
+
}
|
|
303
|
+
if (hours) {
|
|
304
|
+
result += pad(hours) + 'h:';
|
|
305
|
+
}
|
|
306
|
+
result += pad(minutes) + 'm:' + pad(seconds) + 's';
|
|
307
|
+
return result;
|
|
308
|
+
}
|
|
309
|
+
function pad(value) {
|
|
310
|
+
if (value === 0) {
|
|
311
|
+
return '00';
|
|
312
|
+
}
|
|
313
|
+
return value >= 10 ? value.toString() : '0' + value;
|
|
287
314
|
}
|
|
288
315
|
|
|
289
316
|
/**
|
|
@@ -744,9 +771,9 @@ function formatDummyToken(tokenErrorData) {
|
|
|
744
771
|
function getToken$2(appCheck, forceRefresh) {
|
|
745
772
|
if (forceRefresh === void 0) { forceRefresh = false; }
|
|
746
773
|
return tslib.__awaiter(this, void 0, void 0, function () {
|
|
747
|
-
var app, state, token, error, cachedToken,
|
|
748
|
-
return tslib.__generator(this, function (
|
|
749
|
-
switch (
|
|
774
|
+
var app, state, token, error, cachedToken, shouldCallListeners, _a, _b, _c, _d, tokenFromDebugExchange, e_1, interopTokenResult;
|
|
775
|
+
return tslib.__generator(this, function (_e) {
|
|
776
|
+
switch (_e.label) {
|
|
750
777
|
case 0:
|
|
751
778
|
app = appCheck.app;
|
|
752
779
|
ensureActivated(app);
|
|
@@ -756,14 +783,11 @@ function getToken$2(appCheck, forceRefresh) {
|
|
|
756
783
|
if (!!token) return [3 /*break*/, 2];
|
|
757
784
|
return [4 /*yield*/, state.cachedTokenPromise];
|
|
758
785
|
case 1:
|
|
759
|
-
cachedToken =
|
|
786
|
+
cachedToken = _e.sent();
|
|
760
787
|
if (cachedToken && isValid(cachedToken)) {
|
|
761
788
|
token = cachedToken;
|
|
762
|
-
setState(app, tslib.__assign(tslib.__assign({}, state), { token: token }));
|
|
763
|
-
// notify all listeners with the cached token
|
|
764
|
-
notifyTokenListeners(app, { token: token.token });
|
|
765
789
|
}
|
|
766
|
-
|
|
790
|
+
_e.label = 2;
|
|
767
791
|
case 2:
|
|
768
792
|
// Return the cached token (from either memory or indexedDB) if it's valid
|
|
769
793
|
if (!forceRefresh && token && isValid(token)) {
|
|
@@ -771,44 +795,69 @@ function getToken$2(appCheck, forceRefresh) {
|
|
|
771
795
|
token: token.token
|
|
772
796
|
}];
|
|
773
797
|
}
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
798
|
+
shouldCallListeners = false;
|
|
799
|
+
if (!isDebugMode()) return [3 /*break*/, 7];
|
|
800
|
+
if (!!state.exchangeTokenPromise) return [3 /*break*/, 4];
|
|
801
|
+
_a = state;
|
|
802
|
+
_b = exchangeToken;
|
|
803
|
+
_c = getExchangeDebugTokenRequest;
|
|
804
|
+
_d = [app];
|
|
778
805
|
return [4 /*yield*/, getDebugToken()];
|
|
779
|
-
case 3:
|
|
780
|
-
|
|
781
|
-
|
|
806
|
+
case 3:
|
|
807
|
+
_a.exchangeTokenPromise = _b.apply(void 0, [_c.apply(void 0, _d.concat([_e.sent()])), appCheck.platformLoggerProvider]).then(function (token) {
|
|
808
|
+
state.exchangeTokenPromise = undefined;
|
|
809
|
+
return token;
|
|
810
|
+
});
|
|
811
|
+
shouldCallListeners = true;
|
|
812
|
+
_e.label = 4;
|
|
813
|
+
case 4: return [4 /*yield*/, state.exchangeTokenPromise];
|
|
814
|
+
case 5:
|
|
815
|
+
tokenFromDebugExchange = _e.sent();
|
|
782
816
|
// Write debug token to indexedDB.
|
|
783
817
|
return [4 /*yield*/, writeTokenToStorage(app, tokenFromDebugExchange)];
|
|
784
|
-
case
|
|
818
|
+
case 6:
|
|
785
819
|
// Write debug token to indexedDB.
|
|
786
|
-
|
|
820
|
+
_e.sent();
|
|
787
821
|
// Write debug token to state.
|
|
788
822
|
setState(app, tslib.__assign(tslib.__assign({}, state), { token: tokenFromDebugExchange }));
|
|
789
823
|
return [2 /*return*/, { token: tokenFromDebugExchange.token }];
|
|
790
|
-
case 6:
|
|
791
|
-
_d.trys.push([6, 8, , 9]);
|
|
792
|
-
return [4 /*yield*/, state.provider.getToken()];
|
|
793
824
|
case 7:
|
|
794
|
-
|
|
795
|
-
//
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
825
|
+
_e.trys.push([7, 9, , 10]);
|
|
826
|
+
// Avoid making another call to the exchange endpoint if one is in flight.
|
|
827
|
+
if (!state.exchangeTokenPromise) {
|
|
828
|
+
// state.provider is populated in initializeAppCheck()
|
|
829
|
+
// ensureActivated() at the top of this function checks that
|
|
830
|
+
// initializeAppCheck() has been called.
|
|
831
|
+
state.exchangeTokenPromise = state.provider.getToken().then(function (token) {
|
|
832
|
+
state.exchangeTokenPromise = undefined;
|
|
833
|
+
return token;
|
|
834
|
+
});
|
|
835
|
+
shouldCallListeners = true;
|
|
836
|
+
}
|
|
837
|
+
return [4 /*yield*/, state.exchangeTokenPromise];
|
|
799
838
|
case 8:
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
logger.error(e_1);
|
|
803
|
-
error = e_1;
|
|
804
|
-
return [3 /*break*/, 9];
|
|
839
|
+
token = _e.sent();
|
|
840
|
+
return [3 /*break*/, 10];
|
|
805
841
|
case 9:
|
|
806
|
-
|
|
842
|
+
e_1 = _e.sent();
|
|
843
|
+
if (e_1.code === "appCheck/" + "throttled" /* THROTTLED */) {
|
|
844
|
+
// Warn if throttled, but do not treat it as an error.
|
|
845
|
+
logger.warn(e_1.message);
|
|
846
|
+
}
|
|
847
|
+
else {
|
|
848
|
+
// `getToken()` should never throw, but logging error text to console will aid debugging.
|
|
849
|
+
logger.error(e_1);
|
|
850
|
+
}
|
|
851
|
+
// Always save error to be added to dummy token.
|
|
852
|
+
error = e_1;
|
|
853
|
+
return [3 /*break*/, 10];
|
|
854
|
+
case 10:
|
|
855
|
+
if (!!token) return [3 /*break*/, 11];
|
|
807
856
|
// if token is undefined, there must be an error.
|
|
808
857
|
// we return a dummy token along with the error
|
|
809
858
|
interopTokenResult = makeDummyTokenResult(error);
|
|
810
|
-
return [3 /*break*/,
|
|
811
|
-
case
|
|
859
|
+
return [3 /*break*/, 13];
|
|
860
|
+
case 11:
|
|
812
861
|
interopTokenResult = {
|
|
813
862
|
token: token.token
|
|
814
863
|
};
|
|
@@ -816,11 +865,13 @@ function getToken$2(appCheck, forceRefresh) {
|
|
|
816
865
|
// Only do it if we got a valid new token
|
|
817
866
|
setState(app, tslib.__assign(tslib.__assign({}, state), { token: token }));
|
|
818
867
|
return [4 /*yield*/, writeTokenToStorage(app, token)];
|
|
819
|
-
case 11:
|
|
820
|
-
_d.sent();
|
|
821
|
-
_d.label = 12;
|
|
822
868
|
case 12:
|
|
823
|
-
|
|
869
|
+
_e.sent();
|
|
870
|
+
_e.label = 13;
|
|
871
|
+
case 13:
|
|
872
|
+
if (shouldCallListeners) {
|
|
873
|
+
notifyTokenListeners(app, interopTokenResult);
|
|
874
|
+
}
|
|
824
875
|
return [2 /*return*/, interopTokenResult];
|
|
825
876
|
}
|
|
826
877
|
});
|
|
@@ -834,44 +885,31 @@ function addTokenListener(appCheck, type, listener, onError) {
|
|
|
834
885
|
error: onError,
|
|
835
886
|
type: type
|
|
836
887
|
};
|
|
837
|
-
|
|
838
|
-
/**
|
|
839
|
-
* Invoke the listener with the valid token, then start the token refresher
|
|
840
|
-
*/
|
|
841
|
-
if (!newState.tokenRefresher) {
|
|
842
|
-
var tokenRefresher = createTokenRefresher(appCheck);
|
|
843
|
-
newState.tokenRefresher = tokenRefresher;
|
|
844
|
-
}
|
|
845
|
-
// Create the refresher but don't start it if `isTokenAutoRefreshEnabled`
|
|
846
|
-
// is not true.
|
|
847
|
-
if (!newState.tokenRefresher.isRunning() && state.isTokenAutoRefreshEnabled) {
|
|
848
|
-
newState.tokenRefresher.start();
|
|
849
|
-
}
|
|
888
|
+
setState(app, tslib.__assign(tslib.__assign({}, state), { tokenObservers: tslib.__spreadArray(tslib.__spreadArray([], state.tokenObservers), [tokenObserver]) }));
|
|
850
889
|
// Invoke the listener async immediately if there is a valid token
|
|
851
890
|
// in memory.
|
|
852
891
|
if (state.token && isValid(state.token)) {
|
|
853
892
|
var validToken_1 = state.token;
|
|
854
893
|
Promise.resolve()
|
|
855
|
-
.then(function () {
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
});
|
|
859
|
-
}
|
|
860
|
-
else if (state.token == null) {
|
|
861
|
-
// Only check cache if there was no token. If the token was invalid,
|
|
862
|
-
// skip this and rely on exchange endpoint.
|
|
863
|
-
void state
|
|
864
|
-
.cachedTokenPromise // Storage token promise. Always populated in `activate()`.
|
|
865
|
-
.then(function (cachedToken) {
|
|
866
|
-
if (cachedToken && isValid(cachedToken)) {
|
|
867
|
-
listener({ token: cachedToken.token });
|
|
868
|
-
}
|
|
894
|
+
.then(function () {
|
|
895
|
+
listener({ token: validToken_1.token });
|
|
896
|
+
initTokenRefresher(appCheck);
|
|
869
897
|
})
|
|
870
898
|
.catch(function () {
|
|
871
|
-
|
|
899
|
+
/* we don't care about exceptions thrown in listeners */
|
|
872
900
|
});
|
|
873
901
|
}
|
|
874
|
-
|
|
902
|
+
/**
|
|
903
|
+
* Wait for any cached token promise to resolve before starting the token
|
|
904
|
+
* refresher. The refresher checks to see if there is an existing token
|
|
905
|
+
* in state and calls the exchange endpoint if not. We should first let the
|
|
906
|
+
* IndexedDB check have a chance to populate state if it can.
|
|
907
|
+
*
|
|
908
|
+
* Listener call isn't needed here because cachedTokenPromise will call any
|
|
909
|
+
* listeners that exist when it resolves.
|
|
910
|
+
*/
|
|
911
|
+
// state.cachedTokenPromise is always populated in `activate()`.
|
|
912
|
+
void state.cachedTokenPromise.then(function () { return initTokenRefresher(appCheck); });
|
|
875
913
|
}
|
|
876
914
|
function removeTokenListener(app, listener) {
|
|
877
915
|
var state = getState(app);
|
|
@@ -883,6 +921,23 @@ function removeTokenListener(app, listener) {
|
|
|
883
921
|
}
|
|
884
922
|
setState(app, tslib.__assign(tslib.__assign({}, state), { tokenObservers: newObservers }));
|
|
885
923
|
}
|
|
924
|
+
/**
|
|
925
|
+
* Logic to create and start refresher as needed.
|
|
926
|
+
*/
|
|
927
|
+
function initTokenRefresher(appCheck) {
|
|
928
|
+
var app = appCheck.app;
|
|
929
|
+
var state = getState(app);
|
|
930
|
+
// Create the refresher but don't start it if `isTokenAutoRefreshEnabled`
|
|
931
|
+
// is not true.
|
|
932
|
+
var refresher = state.tokenRefresher;
|
|
933
|
+
if (!refresher) {
|
|
934
|
+
refresher = createTokenRefresher(appCheck);
|
|
935
|
+
setState(app, tslib.__assign(tslib.__assign({}, state), { tokenRefresher: refresher }));
|
|
936
|
+
}
|
|
937
|
+
if (!refresher.isRunning() && state.isTokenAutoRefreshEnabled) {
|
|
938
|
+
refresher.start();
|
|
939
|
+
}
|
|
940
|
+
}
|
|
886
941
|
function createTokenRefresher(appCheck) {
|
|
887
942
|
var _this = this;
|
|
888
943
|
var app = appCheck.app;
|
|
@@ -913,7 +968,6 @@ function createTokenRefresher(appCheck) {
|
|
|
913
968
|
}
|
|
914
969
|
});
|
|
915
970
|
}); }, function () {
|
|
916
|
-
// TODO: when should we retry?
|
|
917
971
|
return true;
|
|
918
972
|
}, function () {
|
|
919
973
|
var state = getState(app);
|
|
@@ -1014,7 +1068,7 @@ function internalFactory(appCheck) {
|
|
|
1014
1068
|
}
|
|
1015
1069
|
|
|
1016
1070
|
var name = "@firebase/app-check";
|
|
1017
|
-
var version = "0.5.
|
|
1071
|
+
var version = "0.5.2";
|
|
1018
1072
|
|
|
1019
1073
|
/**
|
|
1020
1074
|
* @license
|
|
@@ -1181,23 +1235,53 @@ var ReCaptchaV3Provider = /** @class */ (function () {
|
|
|
1181
1235
|
*/
|
|
1182
1236
|
function ReCaptchaV3Provider(_siteKey) {
|
|
1183
1237
|
this._siteKey = _siteKey;
|
|
1238
|
+
/**
|
|
1239
|
+
* Throttle requests on certain error codes to prevent too many retries
|
|
1240
|
+
* in a short time.
|
|
1241
|
+
*/
|
|
1242
|
+
this._throttleData = null;
|
|
1184
1243
|
}
|
|
1185
1244
|
/**
|
|
1186
1245
|
* Returns an App Check token.
|
|
1187
1246
|
* @internal
|
|
1188
1247
|
*/
|
|
1189
1248
|
ReCaptchaV3Provider.prototype.getToken = function () {
|
|
1249
|
+
var _a;
|
|
1190
1250
|
return tslib.__awaiter(this, void 0, void 0, function () {
|
|
1191
|
-
var attestedClaimsToken;
|
|
1192
|
-
return tslib.__generator(this, function (
|
|
1193
|
-
switch (
|
|
1194
|
-
case 0:
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1251
|
+
var attestedClaimsToken, result, e_1;
|
|
1252
|
+
return tslib.__generator(this, function (_b) {
|
|
1253
|
+
switch (_b.label) {
|
|
1254
|
+
case 0:
|
|
1255
|
+
throwIfThrottled(this._throttleData);
|
|
1256
|
+
return [4 /*yield*/, getToken$1(this._app).catch(function (_e) {
|
|
1257
|
+
// reCaptcha.execute() throws null which is not very descriptive.
|
|
1258
|
+
throw ERROR_FACTORY.create("recaptcha-error" /* RECAPTCHA_ERROR */);
|
|
1259
|
+
})];
|
|
1198
1260
|
case 1:
|
|
1199
|
-
attestedClaimsToken =
|
|
1200
|
-
|
|
1261
|
+
attestedClaimsToken = _b.sent();
|
|
1262
|
+
_b.label = 2;
|
|
1263
|
+
case 2:
|
|
1264
|
+
_b.trys.push([2, 4, , 5]);
|
|
1265
|
+
return [4 /*yield*/, exchangeToken(getExchangeRecaptchaV3TokenRequest(this._app, attestedClaimsToken), this._platformLoggerProvider)];
|
|
1266
|
+
case 3:
|
|
1267
|
+
result = _b.sent();
|
|
1268
|
+
return [3 /*break*/, 5];
|
|
1269
|
+
case 4:
|
|
1270
|
+
e_1 = _b.sent();
|
|
1271
|
+
if (e_1.code === "fetch-status-error" /* FETCH_STATUS_ERROR */) {
|
|
1272
|
+
this._throttleData = setBackoff(Number((_a = e_1.customData) === null || _a === void 0 ? void 0 : _a.httpStatus), this._throttleData);
|
|
1273
|
+
throw ERROR_FACTORY.create("throttled" /* THROTTLED */, {
|
|
1274
|
+
time: getDurationString(this._throttleData.allowRequestsAfter - Date.now()),
|
|
1275
|
+
httpStatus: this._throttleData.httpStatus
|
|
1276
|
+
});
|
|
1277
|
+
}
|
|
1278
|
+
else {
|
|
1279
|
+
throw e_1;
|
|
1280
|
+
}
|
|
1281
|
+
case 5:
|
|
1282
|
+
// If successful, clear throttle data.
|
|
1283
|
+
this._throttleData = null;
|
|
1284
|
+
return [2 /*return*/, result];
|
|
1201
1285
|
}
|
|
1202
1286
|
});
|
|
1203
1287
|
});
|
|
@@ -1238,23 +1322,53 @@ var ReCaptchaEnterpriseProvider = /** @class */ (function () {
|
|
|
1238
1322
|
*/
|
|
1239
1323
|
function ReCaptchaEnterpriseProvider(_siteKey) {
|
|
1240
1324
|
this._siteKey = _siteKey;
|
|
1325
|
+
/**
|
|
1326
|
+
* Throttle requests on certain error codes to prevent too many retries
|
|
1327
|
+
* in a short time.
|
|
1328
|
+
*/
|
|
1329
|
+
this._throttleData = null;
|
|
1241
1330
|
}
|
|
1242
1331
|
/**
|
|
1243
1332
|
* Returns an App Check token.
|
|
1244
1333
|
* @internal
|
|
1245
1334
|
*/
|
|
1246
1335
|
ReCaptchaEnterpriseProvider.prototype.getToken = function () {
|
|
1336
|
+
var _a;
|
|
1247
1337
|
return tslib.__awaiter(this, void 0, void 0, function () {
|
|
1248
|
-
var attestedClaimsToken;
|
|
1249
|
-
return tslib.__generator(this, function (
|
|
1250
|
-
switch (
|
|
1251
|
-
case 0:
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1338
|
+
var attestedClaimsToken, result, e_2;
|
|
1339
|
+
return tslib.__generator(this, function (_b) {
|
|
1340
|
+
switch (_b.label) {
|
|
1341
|
+
case 0:
|
|
1342
|
+
throwIfThrottled(this._throttleData);
|
|
1343
|
+
return [4 /*yield*/, getToken$1(this._app).catch(function (_e) {
|
|
1344
|
+
// reCaptcha.execute() throws null which is not very descriptive.
|
|
1345
|
+
throw ERROR_FACTORY.create("recaptcha-error" /* RECAPTCHA_ERROR */);
|
|
1346
|
+
})];
|
|
1255
1347
|
case 1:
|
|
1256
|
-
attestedClaimsToken =
|
|
1257
|
-
|
|
1348
|
+
attestedClaimsToken = _b.sent();
|
|
1349
|
+
_b.label = 2;
|
|
1350
|
+
case 2:
|
|
1351
|
+
_b.trys.push([2, 4, , 5]);
|
|
1352
|
+
return [4 /*yield*/, exchangeToken(getExchangeRecaptchaEnterpriseTokenRequest(this._app, attestedClaimsToken), this._platformLoggerProvider)];
|
|
1353
|
+
case 3:
|
|
1354
|
+
result = _b.sent();
|
|
1355
|
+
return [3 /*break*/, 5];
|
|
1356
|
+
case 4:
|
|
1357
|
+
e_2 = _b.sent();
|
|
1358
|
+
if (e_2.code === "fetch-status-error" /* FETCH_STATUS_ERROR */) {
|
|
1359
|
+
this._throttleData = setBackoff(Number((_a = e_2.customData) === null || _a === void 0 ? void 0 : _a.httpStatus), this._throttleData);
|
|
1360
|
+
throw ERROR_FACTORY.create("throttled" /* THROTTLED */, {
|
|
1361
|
+
time: getDurationString(this._throttleData.allowRequestsAfter - Date.now()),
|
|
1362
|
+
httpStatus: this._throttleData.httpStatus
|
|
1363
|
+
});
|
|
1364
|
+
}
|
|
1365
|
+
else {
|
|
1366
|
+
throw e_2;
|
|
1367
|
+
}
|
|
1368
|
+
case 5:
|
|
1369
|
+
// If successful, clear throttle data.
|
|
1370
|
+
this._throttleData = null;
|
|
1371
|
+
return [2 /*return*/, result];
|
|
1258
1372
|
}
|
|
1259
1373
|
});
|
|
1260
1374
|
});
|
|
@@ -1331,7 +1445,58 @@ var CustomProvider = /** @class */ (function () {
|
|
|
1331
1445
|
}
|
|
1332
1446
|
};
|
|
1333
1447
|
return CustomProvider;
|
|
1334
|
-
}());
|
|
1448
|
+
}());
|
|
1449
|
+
/**
|
|
1450
|
+
* Set throttle data to block requests until after a certain time
|
|
1451
|
+
* depending on the failed request's status code.
|
|
1452
|
+
* @param httpStatus - Status code of failed request.
|
|
1453
|
+
* @param throttleData - `ThrottleData` object containing previous throttle
|
|
1454
|
+
* data state.
|
|
1455
|
+
* @returns Data about current throttle state and expiration time.
|
|
1456
|
+
*/
|
|
1457
|
+
function setBackoff(httpStatus, throttleData) {
|
|
1458
|
+
/**
|
|
1459
|
+
* Block retries for 1 day for the following error codes:
|
|
1460
|
+
*
|
|
1461
|
+
* 404: Likely malformed URL.
|
|
1462
|
+
*
|
|
1463
|
+
* 403:
|
|
1464
|
+
* - Attestation failed
|
|
1465
|
+
* - Wrong API key
|
|
1466
|
+
* - Project deleted
|
|
1467
|
+
*/
|
|
1468
|
+
if (httpStatus === 404 || httpStatus === 403) {
|
|
1469
|
+
return {
|
|
1470
|
+
backoffCount: 1,
|
|
1471
|
+
allowRequestsAfter: Date.now() + ONE_DAY,
|
|
1472
|
+
httpStatus: httpStatus
|
|
1473
|
+
};
|
|
1474
|
+
}
|
|
1475
|
+
else {
|
|
1476
|
+
/**
|
|
1477
|
+
* For all other error codes, the time when it is ok to retry again
|
|
1478
|
+
* is based on exponential backoff.
|
|
1479
|
+
*/
|
|
1480
|
+
var backoffCount = throttleData ? throttleData.backoffCount : 0;
|
|
1481
|
+
var backoffMillis = util.calculateBackoffMillis(backoffCount, 1000, 2);
|
|
1482
|
+
return {
|
|
1483
|
+
backoffCount: backoffCount + 1,
|
|
1484
|
+
allowRequestsAfter: Date.now() + backoffMillis,
|
|
1485
|
+
httpStatus: httpStatus
|
|
1486
|
+
};
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
function throwIfThrottled(throttleData) {
|
|
1490
|
+
if (throttleData) {
|
|
1491
|
+
if (Date.now() - throttleData.allowRequestsAfter <= 0) {
|
|
1492
|
+
// If before, throw.
|
|
1493
|
+
throw ERROR_FACTORY.create("throttled" /* THROTTLED */, {
|
|
1494
|
+
time: getDurationString(throttleData.allowRequestsAfter - Date.now()),
|
|
1495
|
+
httpStatus: throttleData.httpStatus
|
|
1496
|
+
});
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1335
1500
|
|
|
1336
1501
|
/**
|
|
1337
1502
|
* @license
|
|
@@ -1388,6 +1553,17 @@ function initializeAppCheck(app$1, options) {
|
|
|
1388
1553
|
}
|
|
1389
1554
|
var appCheck = provider.initialize({ options: options });
|
|
1390
1555
|
_activate(app$1, options.provider, options.isTokenAutoRefreshEnabled);
|
|
1556
|
+
// If isTokenAutoRefreshEnabled is false, do not send any requests to the
|
|
1557
|
+
// exchange endpoint without an explicit call from the user either directly
|
|
1558
|
+
// or through another Firebase library (storage, functions, etc.)
|
|
1559
|
+
if (getState(app$1).isTokenAutoRefreshEnabled) {
|
|
1560
|
+
// Adding a listener will start the refresher and fetch a token if needed.
|
|
1561
|
+
// This gets a token ready and prevents a delay when an internal library
|
|
1562
|
+
// requests the token.
|
|
1563
|
+
// Listener function does not need to do anything, its base functionality
|
|
1564
|
+
// of calling getToken() already fetches token and writes it to memory/storage.
|
|
1565
|
+
addTokenListener(appCheck, "INTERNAL" /* INTERNAL */, function () { });
|
|
1566
|
+
}
|
|
1391
1567
|
return appCheck;
|
|
1392
1568
|
}
|
|
1393
1569
|
/**
|
|
@@ -1407,6 +1583,8 @@ function _activate(app, provider, isTokenAutoRefreshEnabled) {
|
|
|
1407
1583
|
newState.cachedTokenPromise = readTokenFromStorage(app).then(function (cachedToken) {
|
|
1408
1584
|
if (cachedToken && isValid(cachedToken)) {
|
|
1409
1585
|
setState(app, tslib.__assign(tslib.__assign({}, getState(app)), { token: cachedToken }));
|
|
1586
|
+
// notify all listeners with the cached token
|
|
1587
|
+
notifyTokenListeners(app, { token: cachedToken.token });
|
|
1410
1588
|
}
|
|
1411
1589
|
return cachedToken;
|
|
1412
1590
|
});
|