@firebase/app-check 0.8.8 → 0.8.9

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/dist/index.cjs.js CHANGED
@@ -4,7 +4,6 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var app = require('@firebase/app');
6
6
  var component = require('@firebase/component');
7
- var tslib = require('tslib');
8
7
  var util = require('@firebase/util');
9
8
  var logger$1 = require('@firebase/logger');
10
9
 
@@ -24,12 +23,12 @@ var logger$1 = require('@firebase/logger');
24
23
  * See the License for the specific language governing permissions and
25
24
  * limitations under the License.
26
25
  */
27
- var APP_CHECK_STATES = new Map();
28
- var DEFAULT_STATE = {
26
+ const APP_CHECK_STATES = new Map();
27
+ const DEFAULT_STATE = {
29
28
  activated: false,
30
29
  tokenObservers: []
31
30
  };
32
- var DEBUG_STATE = {
31
+ const DEBUG_STATE = {
33
32
  initialized: false,
34
33
  enabled: false
35
34
  };
@@ -37,7 +36,7 @@ var DEBUG_STATE = {
37
36
  * Gets a reference to the state object.
38
37
  */
39
38
  function getStateReference(app) {
40
- return APP_CHECK_STATES.get(app) || tslib.__assign({}, DEFAULT_STATE);
39
+ return APP_CHECK_STATES.get(app) || Object.assign({}, DEFAULT_STATE);
41
40
  }
42
41
  /**
43
42
  * Set once on initialization. The map should hold the same reference to the
@@ -67,11 +66,11 @@ function getDebugState() {
67
66
  * See the License for the specific language governing permissions and
68
67
  * limitations under the License.
69
68
  */
70
- var BASE_ENDPOINT = 'https://content-firebaseappcheck.googleapis.com/v1';
71
- var EXCHANGE_RECAPTCHA_TOKEN_METHOD = 'exchangeRecaptchaV3Token';
72
- var EXCHANGE_RECAPTCHA_ENTERPRISE_TOKEN_METHOD = 'exchangeRecaptchaEnterpriseToken';
73
- var EXCHANGE_DEBUG_TOKEN_METHOD = 'exchangeDebugToken';
74
- var TOKEN_REFRESH_TIME = {
69
+ const BASE_ENDPOINT = 'https://content-firebaseappcheck.googleapis.com/v1';
70
+ const EXCHANGE_RECAPTCHA_TOKEN_METHOD = 'exchangeRecaptchaV3Token';
71
+ const EXCHANGE_RECAPTCHA_ENTERPRISE_TOKEN_METHOD = 'exchangeRecaptchaEnterpriseToken';
72
+ const EXCHANGE_DEBUG_TOKEN_METHOD = 'exchangeDebugToken';
73
+ const TOKEN_REFRESH_TIME = {
75
74
  /**
76
75
  * The offset time before token natural expiration to run the refresh.
77
76
  * This is currently 5 minutes.
@@ -90,7 +89,7 @@ var TOKEN_REFRESH_TIME = {
90
89
  /**
91
90
  * One day in millis, for certain error code backoffs.
92
91
  */
93
- var ONE_DAY = 24 * 60 * 60 * 1000;
92
+ const ONE_DAY = 24 * 60 * 60 * 1000;
94
93
 
95
94
  /**
96
95
  * @license
@@ -114,8 +113,8 @@ var ONE_DAY = 24 * 60 * 60 * 1000;
114
113
  */
115
114
  // TODO: move it to @firebase/util?
116
115
  // TODO: allow to config whether refresh should happen in the background
117
- var Refresher = /** @class */ (function () {
118
- function Refresher(operation, retryPolicy, getWaitDuration, lowerBound, upperBound) {
116
+ class Refresher {
117
+ constructor(operation, retryPolicy, getWaitDuration, lowerBound, upperBound) {
119
118
  this.operation = operation;
120
119
  this.retryPolicy = retryPolicy;
121
120
  this.getWaitDuration = getWaitDuration;
@@ -127,79 +126,59 @@ var Refresher = /** @class */ (function () {
127
126
  throw new Error('Proactive refresh lower bound greater than upper bound!');
128
127
  }
129
128
  }
130
- Refresher.prototype.start = function () {
129
+ start() {
131
130
  this.nextErrorWaitInterval = this.lowerBound;
132
- this.process(true).catch(function () {
131
+ this.process(true).catch(() => {
133
132
  /* we don't care about the result */
134
133
  });
135
- };
136
- Refresher.prototype.stop = function () {
134
+ }
135
+ stop() {
137
136
  if (this.pending) {
138
137
  this.pending.reject('cancelled');
139
138
  this.pending = null;
140
139
  }
141
- };
142
- Refresher.prototype.isRunning = function () {
140
+ }
141
+ isRunning() {
143
142
  return !!this.pending;
144
- };
145
- Refresher.prototype.process = function (hasSucceeded) {
146
- return tslib.__awaiter(this, void 0, void 0, function () {
147
- var error_1;
148
- return tslib.__generator(this, function (_a) {
149
- switch (_a.label) {
150
- case 0:
151
- this.stop();
152
- _a.label = 1;
153
- case 1:
154
- _a.trys.push([1, 6, , 7]);
155
- this.pending = new util.Deferred();
156
- this.pending.promise.catch(function (_e) {
157
- /* ignore */
158
- });
159
- return [4 /*yield*/, sleep(this.getNextRun(hasSucceeded))];
160
- case 2:
161
- _a.sent();
162
- // Why do we resolve a promise, then immediate wait for it?
163
- // We do it to make the promise chain cancellable.
164
- // We can call stop() which rejects the promise before the following line execute, which makes
165
- // the code jump to the catch block.
166
- // TODO: unit test this
167
- this.pending.resolve();
168
- return [4 /*yield*/, this.pending.promise];
169
- case 3:
170
- _a.sent();
171
- this.pending = new util.Deferred();
172
- this.pending.promise.catch(function (_e) {
173
- /* ignore */
174
- });
175
- return [4 /*yield*/, this.operation()];
176
- case 4:
177
- _a.sent();
178
- this.pending.resolve();
179
- return [4 /*yield*/, this.pending.promise];
180
- case 5:
181
- _a.sent();
182
- this.process(true).catch(function () {
183
- /* we don't care about the result */
184
- });
185
- return [3 /*break*/, 7];
186
- case 6:
187
- error_1 = _a.sent();
188
- if (this.retryPolicy(error_1)) {
189
- this.process(false).catch(function () {
190
- /* we don't care about the result */
191
- });
192
- }
193
- else {
194
- this.stop();
195
- }
196
- return [3 /*break*/, 7];
197
- case 7: return [2 /*return*/];
198
- }
143
+ }
144
+ async process(hasSucceeded) {
145
+ this.stop();
146
+ try {
147
+ this.pending = new util.Deferred();
148
+ this.pending.promise.catch(_e => {
149
+ /* ignore */
199
150
  });
200
- });
201
- };
202
- Refresher.prototype.getNextRun = function (hasSucceeded) {
151
+ await sleep(this.getNextRun(hasSucceeded));
152
+ // Why do we resolve a promise, then immediate wait for it?
153
+ // We do it to make the promise chain cancellable.
154
+ // We can call stop() which rejects the promise before the following line execute, which makes
155
+ // the code jump to the catch block.
156
+ // TODO: unit test this
157
+ this.pending.resolve();
158
+ await this.pending.promise;
159
+ this.pending = new util.Deferred();
160
+ this.pending.promise.catch(_e => {
161
+ /* ignore */
162
+ });
163
+ await this.operation();
164
+ this.pending.resolve();
165
+ await this.pending.promise;
166
+ this.process(true).catch(() => {
167
+ /* we don't care about the result */
168
+ });
169
+ }
170
+ catch (error) {
171
+ if (this.retryPolicy(error)) {
172
+ this.process(false).catch(() => {
173
+ /* we don't care about the result */
174
+ });
175
+ }
176
+ else {
177
+ this.stop();
178
+ }
179
+ }
180
+ }
181
+ getNextRun(hasSucceeded) {
203
182
  if (hasSucceeded) {
204
183
  // If last operation succeeded, reset next error wait interval and return
205
184
  // the default wait duration.
@@ -209,7 +188,7 @@ var Refresher = /** @class */ (function () {
209
188
  }
210
189
  else {
211
190
  // Get next error wait interval.
212
- var currentErrorWaitInterval = this.nextErrorWaitInterval;
191
+ const currentErrorWaitInterval = this.nextErrorWaitInterval;
213
192
  // Double interval for next consecutive error.
214
193
  this.nextErrorWaitInterval *= 2;
215
194
  // Make sure next wait interval does not exceed the maximum upper bound.
@@ -218,11 +197,10 @@ var Refresher = /** @class */ (function () {
218
197
  }
219
198
  return currentErrorWaitInterval;
220
199
  }
221
- };
222
- return Refresher;
223
- }());
200
+ }
201
+ }
224
202
  function sleep(ms) {
225
- return new Promise(function (resolve) {
203
+ return new Promise(resolve => {
226
204
  setTimeout(resolve, ms);
227
205
  });
228
206
  }
@@ -243,26 +221,25 @@ function sleep(ms) {
243
221
  * See the License for the specific language governing permissions and
244
222
  * limitations under the License.
245
223
  */
246
- var _a;
247
- var ERRORS = (_a = {},
248
- _a["already-initialized" /* AppCheckError.ALREADY_INITIALIZED */] = 'You have already called initializeAppCheck() for FirebaseApp {$appName} with ' +
224
+ const ERRORS = {
225
+ ["already-initialized" /* AppCheckError.ALREADY_INITIALIZED */]: 'You have already called initializeAppCheck() for FirebaseApp {$appName} with ' +
249
226
  'different options. To avoid this error, call initializeAppCheck() with the ' +
250
227
  'same options as when it was originally called. This will return the ' +
251
228
  'already initialized instance.',
252
- _a["use-before-activation" /* AppCheckError.USE_BEFORE_ACTIVATION */] = 'App Check is being used before initializeAppCheck() is called for FirebaseApp {$appName}. ' +
229
+ ["use-before-activation" /* AppCheckError.USE_BEFORE_ACTIVATION */]: 'App Check is being used before initializeAppCheck() is called for FirebaseApp {$appName}. ' +
253
230
  'Call initializeAppCheck() before instantiating other Firebase services.',
254
- _a["fetch-network-error" /* AppCheckError.FETCH_NETWORK_ERROR */] = 'Fetch failed to connect to a network. Check Internet connection. ' +
231
+ ["fetch-network-error" /* AppCheckError.FETCH_NETWORK_ERROR */]: 'Fetch failed to connect to a network. Check Internet connection. ' +
255
232
  'Original error: {$originalErrorMessage}.',
256
- _a["fetch-parse-error" /* AppCheckError.FETCH_PARSE_ERROR */] = 'Fetch client could not parse response.' +
233
+ ["fetch-parse-error" /* AppCheckError.FETCH_PARSE_ERROR */]: 'Fetch client could not parse response.' +
257
234
  ' Original error: {$originalErrorMessage}.',
258
- _a["fetch-status-error" /* AppCheckError.FETCH_STATUS_ERROR */] = 'Fetch server returned an HTTP error status. HTTP status: {$httpStatus}.',
259
- _a["storage-open" /* AppCheckError.STORAGE_OPEN */] = 'Error thrown when opening storage. Original error: {$originalErrorMessage}.',
260
- _a["storage-get" /* AppCheckError.STORAGE_GET */] = 'Error thrown when reading from storage. Original error: {$originalErrorMessage}.',
261
- _a["storage-set" /* AppCheckError.STORAGE_WRITE */] = 'Error thrown when writing to storage. Original error: {$originalErrorMessage}.',
262
- _a["recaptcha-error" /* AppCheckError.RECAPTCHA_ERROR */] = 'ReCAPTCHA error.',
263
- _a["throttled" /* AppCheckError.THROTTLED */] = "Requests throttled due to {$httpStatus} error. Attempts allowed again after {$time}",
264
- _a);
265
- var ERROR_FACTORY = new util.ErrorFactory('appCheck', 'AppCheck', ERRORS);
235
+ ["fetch-status-error" /* AppCheckError.FETCH_STATUS_ERROR */]: 'Fetch server returned an HTTP error status. HTTP status: {$httpStatus}.',
236
+ ["storage-open" /* AppCheckError.STORAGE_OPEN */]: 'Error thrown when opening storage. Original error: {$originalErrorMessage}.',
237
+ ["storage-get" /* AppCheckError.STORAGE_GET */]: 'Error thrown when reading from storage. Original error: {$originalErrorMessage}.',
238
+ ["storage-set" /* AppCheckError.STORAGE_WRITE */]: 'Error thrown when writing to storage. Original error: {$originalErrorMessage}.',
239
+ ["recaptcha-error" /* AppCheckError.RECAPTCHA_ERROR */]: 'ReCAPTCHA error.',
240
+ ["throttled" /* AppCheckError.THROTTLED */]: `Requests throttled due to {$httpStatus} error. Attempts allowed again after {$time}`
241
+ };
242
+ const ERROR_FACTORY = new util.ErrorFactory('appCheck', 'AppCheck', ERRORS);
266
243
 
267
244
  /**
268
245
  * @license
@@ -280,9 +257,8 @@ var ERROR_FACTORY = new util.ErrorFactory('appCheck', 'AppCheck', ERRORS);
280
257
  * See the License for the specific language governing permissions and
281
258
  * limitations under the License.
282
259
  */
283
- function getRecaptcha(isEnterprise) {
260
+ function getRecaptcha(isEnterprise = false) {
284
261
  var _a;
285
- if (isEnterprise === void 0) { isEnterprise = false; }
286
262
  if (isEnterprise) {
287
263
  return (_a = self.grecaptcha) === null || _a === void 0 ? void 0 : _a.enterprise;
288
264
  }
@@ -296,12 +272,12 @@ function ensureActivated(app) {
296
272
  }
297
273
  }
298
274
  function getDurationString(durationInMillis) {
299
- var totalSeconds = Math.round(durationInMillis / 1000);
300
- var days = Math.floor(totalSeconds / (3600 * 24));
301
- var hours = Math.floor((totalSeconds - days * 3600 * 24) / 3600);
302
- var minutes = Math.floor((totalSeconds - days * 3600 * 24 - hours * 3600) / 60);
303
- var seconds = totalSeconds - days * 3600 * 24 - hours * 3600 - minutes * 60;
304
- var result = '';
275
+ const totalSeconds = Math.round(durationInMillis / 1000);
276
+ const days = Math.floor(totalSeconds / (3600 * 24));
277
+ const hours = Math.floor((totalSeconds - days * 3600 * 24) / 3600);
278
+ const minutes = Math.floor((totalSeconds - days * 3600 * 24 - hours * 3600) / 60);
279
+ const seconds = totalSeconds - days * 3600 * 24 - hours * 3600 - minutes * 60;
280
+ let result = '';
305
281
  if (days) {
306
282
  result += pad(days) + 'd:';
307
283
  }
@@ -334,105 +310,88 @@ function pad(value) {
334
310
  * See the License for the specific language governing permissions and
335
311
  * limitations under the License.
336
312
  */
337
- function exchangeToken(_a, heartbeatServiceProvider) {
338
- var url = _a.url, body = _a.body;
339
- return tslib.__awaiter(this, void 0, void 0, function () {
340
- var headers, heartbeatService, heartbeatsHeader, options, response, originalError_1, responseBody, originalError_2, match, timeToLiveAsNumber, now;
341
- return tslib.__generator(this, function (_b) {
342
- switch (_b.label) {
343
- case 0:
344
- headers = {
345
- 'Content-Type': 'application/json'
346
- };
347
- heartbeatService = heartbeatServiceProvider.getImmediate({
348
- optional: true
349
- });
350
- if (!heartbeatService) return [3 /*break*/, 2];
351
- return [4 /*yield*/, heartbeatService.getHeartbeatsHeader()];
352
- case 1:
353
- heartbeatsHeader = _b.sent();
354
- if (heartbeatsHeader) {
355
- headers['X-Firebase-Client'] = heartbeatsHeader;
356
- }
357
- _b.label = 2;
358
- case 2:
359
- options = {
360
- method: 'POST',
361
- body: JSON.stringify(body),
362
- headers: headers
363
- };
364
- _b.label = 3;
365
- case 3:
366
- _b.trys.push([3, 5, , 6]);
367
- return [4 /*yield*/, fetch(url, options)];
368
- case 4:
369
- response = _b.sent();
370
- return [3 /*break*/, 6];
371
- case 5:
372
- originalError_1 = _b.sent();
373
- throw ERROR_FACTORY.create("fetch-network-error" /* AppCheckError.FETCH_NETWORK_ERROR */, {
374
- originalErrorMessage: originalError_1 === null || originalError_1 === void 0 ? void 0 : originalError_1.message
375
- });
376
- case 6:
377
- if (response.status !== 200) {
378
- throw ERROR_FACTORY.create("fetch-status-error" /* AppCheckError.FETCH_STATUS_ERROR */, {
379
- httpStatus: response.status
380
- });
381
- }
382
- _b.label = 7;
383
- case 7:
384
- _b.trys.push([7, 9, , 10]);
385
- return [4 /*yield*/, response.json()];
386
- case 8:
387
- // JSON parsing throws SyntaxError if the response body isn't a JSON string.
388
- responseBody = _b.sent();
389
- return [3 /*break*/, 10];
390
- case 9:
391
- originalError_2 = _b.sent();
392
- throw ERROR_FACTORY.create("fetch-parse-error" /* AppCheckError.FETCH_PARSE_ERROR */, {
393
- originalErrorMessage: originalError_2 === null || originalError_2 === void 0 ? void 0 : originalError_2.message
394
- });
395
- case 10:
396
- match = responseBody.ttl.match(/^([\d.]+)(s)$/);
397
- if (!match || !match[2] || isNaN(Number(match[1]))) {
398
- throw ERROR_FACTORY.create("fetch-parse-error" /* AppCheckError.FETCH_PARSE_ERROR */, {
399
- originalErrorMessage: "ttl field (timeToLive) is not in standard Protobuf Duration " +
400
- "format: ".concat(responseBody.ttl)
401
- });
402
- }
403
- timeToLiveAsNumber = Number(match[1]) * 1000;
404
- now = Date.now();
405
- return [2 /*return*/, {
406
- token: responseBody.token,
407
- expireTimeMillis: now + timeToLiveAsNumber,
408
- issuedAtTimeMillis: now
409
- }];
410
- }
411
- });
313
+ async function exchangeToken({ url, body }, heartbeatServiceProvider) {
314
+ const headers = {
315
+ 'Content-Type': 'application/json'
316
+ };
317
+ // If heartbeat service exists, add heartbeat header string to the header.
318
+ const heartbeatService = heartbeatServiceProvider.getImmediate({
319
+ optional: true
412
320
  });
321
+ if (heartbeatService) {
322
+ const heartbeatsHeader = await heartbeatService.getHeartbeatsHeader();
323
+ if (heartbeatsHeader) {
324
+ headers['X-Firebase-Client'] = heartbeatsHeader;
325
+ }
326
+ }
327
+ const options = {
328
+ method: 'POST',
329
+ body: JSON.stringify(body),
330
+ headers
331
+ };
332
+ let response;
333
+ try {
334
+ response = await fetch(url, options);
335
+ }
336
+ catch (originalError) {
337
+ throw ERROR_FACTORY.create("fetch-network-error" /* AppCheckError.FETCH_NETWORK_ERROR */, {
338
+ originalErrorMessage: originalError === null || originalError === void 0 ? void 0 : originalError.message
339
+ });
340
+ }
341
+ if (response.status !== 200) {
342
+ throw ERROR_FACTORY.create("fetch-status-error" /* AppCheckError.FETCH_STATUS_ERROR */, {
343
+ httpStatus: response.status
344
+ });
345
+ }
346
+ let responseBody;
347
+ try {
348
+ // JSON parsing throws SyntaxError if the response body isn't a JSON string.
349
+ responseBody = await response.json();
350
+ }
351
+ catch (originalError) {
352
+ throw ERROR_FACTORY.create("fetch-parse-error" /* AppCheckError.FETCH_PARSE_ERROR */, {
353
+ originalErrorMessage: originalError === null || originalError === void 0 ? void 0 : originalError.message
354
+ });
355
+ }
356
+ // Protobuf duration format.
357
+ // https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/Duration
358
+ const match = responseBody.ttl.match(/^([\d.]+)(s)$/);
359
+ if (!match || !match[2] || isNaN(Number(match[1]))) {
360
+ throw ERROR_FACTORY.create("fetch-parse-error" /* AppCheckError.FETCH_PARSE_ERROR */, {
361
+ originalErrorMessage: `ttl field (timeToLive) is not in standard Protobuf Duration ` +
362
+ `format: ${responseBody.ttl}`
363
+ });
364
+ }
365
+ const timeToLiveAsNumber = Number(match[1]) * 1000;
366
+ const now = Date.now();
367
+ return {
368
+ token: responseBody.token,
369
+ expireTimeMillis: now + timeToLiveAsNumber,
370
+ issuedAtTimeMillis: now
371
+ };
413
372
  }
414
373
  function getExchangeRecaptchaV3TokenRequest(app, reCAPTCHAToken) {
415
- var _a = app.options, projectId = _a.projectId, appId = _a.appId, apiKey = _a.apiKey;
374
+ const { projectId, appId, apiKey } = app.options;
416
375
  return {
417
- url: "".concat(BASE_ENDPOINT, "/projects/").concat(projectId, "/apps/").concat(appId, ":").concat(EXCHANGE_RECAPTCHA_TOKEN_METHOD, "?key=").concat(apiKey),
376
+ url: `${BASE_ENDPOINT}/projects/${projectId}/apps/${appId}:${EXCHANGE_RECAPTCHA_TOKEN_METHOD}?key=${apiKey}`,
418
377
  body: {
419
378
  'recaptcha_v3_token': reCAPTCHAToken
420
379
  }
421
380
  };
422
381
  }
423
382
  function getExchangeRecaptchaEnterpriseTokenRequest(app, reCAPTCHAToken) {
424
- var _a = app.options, projectId = _a.projectId, appId = _a.appId, apiKey = _a.apiKey;
383
+ const { projectId, appId, apiKey } = app.options;
425
384
  return {
426
- url: "".concat(BASE_ENDPOINT, "/projects/").concat(projectId, "/apps/").concat(appId, ":").concat(EXCHANGE_RECAPTCHA_ENTERPRISE_TOKEN_METHOD, "?key=").concat(apiKey),
385
+ url: `${BASE_ENDPOINT}/projects/${projectId}/apps/${appId}:${EXCHANGE_RECAPTCHA_ENTERPRISE_TOKEN_METHOD}?key=${apiKey}`,
427
386
  body: {
428
387
  'recaptcha_enterprise_token': reCAPTCHAToken
429
388
  }
430
389
  };
431
390
  }
432
391
  function getExchangeDebugTokenRequest(app, debugToken) {
433
- var _a = app.options, projectId = _a.projectId, appId = _a.appId, apiKey = _a.apiKey;
392
+ const { projectId, appId, apiKey } = app.options;
434
393
  return {
435
- url: "".concat(BASE_ENDPOINT, "/projects/").concat(projectId, "/apps/").concat(appId, ":").concat(EXCHANGE_DEBUG_TOKEN_METHOD, "?key=").concat(apiKey),
394
+ url: `${BASE_ENDPOINT}/projects/${projectId}/apps/${appId}:${EXCHANGE_DEBUG_TOKEN_METHOD}?key=${apiKey}`,
436
395
  body: {
437
396
  // eslint-disable-next-line
438
397
  debug_token: debugToken
@@ -456,29 +415,29 @@ function getExchangeDebugTokenRequest(app, debugToken) {
456
415
  * See the License for the specific language governing permissions and
457
416
  * limitations under the License.
458
417
  */
459
- var DB_NAME = 'firebase-app-check-database';
460
- var DB_VERSION = 1;
461
- var STORE_NAME = 'firebase-app-check-store';
462
- var DEBUG_TOKEN_KEY = 'debug-token';
463
- var dbPromise = null;
418
+ const DB_NAME = 'firebase-app-check-database';
419
+ const DB_VERSION = 1;
420
+ const STORE_NAME = 'firebase-app-check-store';
421
+ const DEBUG_TOKEN_KEY = 'debug-token';
422
+ let dbPromise = null;
464
423
  function getDBPromise() {
465
424
  if (dbPromise) {
466
425
  return dbPromise;
467
426
  }
468
- dbPromise = new Promise(function (resolve, reject) {
427
+ dbPromise = new Promise((resolve, reject) => {
469
428
  try {
470
- var request = indexedDB.open(DB_NAME, DB_VERSION);
471
- request.onsuccess = function (event) {
429
+ const request = indexedDB.open(DB_NAME, DB_VERSION);
430
+ request.onsuccess = event => {
472
431
  resolve(event.target.result);
473
432
  };
474
- request.onerror = function (event) {
433
+ request.onerror = event => {
475
434
  var _a;
476
435
  reject(ERROR_FACTORY.create("storage-open" /* AppCheckError.STORAGE_OPEN */, {
477
436
  originalErrorMessage: (_a = event.target.error) === null || _a === void 0 ? void 0 : _a.message
478
437
  }));
479
438
  };
480
- request.onupgradeneeded = function (event) {
481
- var db = event.target.result;
439
+ request.onupgradeneeded = event => {
440
+ const db = event.target.result;
482
441
  // We don't use 'break' in this switch statement, the fall-through
483
442
  // behavior is what we want, because if there are multiple versions between
484
443
  // the old version and the current version, we want ALL the migrations
@@ -512,69 +471,51 @@ function writeDebugTokenToIndexedDB(token) {
512
471
  function readDebugTokenFromIndexedDB() {
513
472
  return read(DEBUG_TOKEN_KEY);
514
473
  }
515
- function write(key, value) {
516
- return tslib.__awaiter(this, void 0, void 0, function () {
517
- var db, transaction, store, request;
518
- return tslib.__generator(this, function (_a) {
519
- switch (_a.label) {
520
- case 0: return [4 /*yield*/, getDBPromise()];
521
- case 1:
522
- db = _a.sent();
523
- transaction = db.transaction(STORE_NAME, 'readwrite');
524
- store = transaction.objectStore(STORE_NAME);
525
- request = store.put({
526
- compositeKey: key,
527
- value: value
528
- });
529
- return [2 /*return*/, new Promise(function (resolve, reject) {
530
- request.onsuccess = function (_event) {
531
- resolve();
532
- };
533
- transaction.onerror = function (event) {
534
- var _a;
535
- reject(ERROR_FACTORY.create("storage-set" /* AppCheckError.STORAGE_WRITE */, {
536
- originalErrorMessage: (_a = event.target.error) === null || _a === void 0 ? void 0 : _a.message
537
- }));
538
- };
539
- })];
540
- }
541
- });
474
+ async function write(key, value) {
475
+ const db = await getDBPromise();
476
+ const transaction = db.transaction(STORE_NAME, 'readwrite');
477
+ const store = transaction.objectStore(STORE_NAME);
478
+ const request = store.put({
479
+ compositeKey: key,
480
+ value
481
+ });
482
+ return new Promise((resolve, reject) => {
483
+ request.onsuccess = _event => {
484
+ resolve();
485
+ };
486
+ transaction.onerror = event => {
487
+ var _a;
488
+ reject(ERROR_FACTORY.create("storage-set" /* AppCheckError.STORAGE_WRITE */, {
489
+ originalErrorMessage: (_a = event.target.error) === null || _a === void 0 ? void 0 : _a.message
490
+ }));
491
+ };
542
492
  });
543
493
  }
544
- function read(key) {
545
- return tslib.__awaiter(this, void 0, void 0, function () {
546
- var db, transaction, store, request;
547
- return tslib.__generator(this, function (_a) {
548
- switch (_a.label) {
549
- case 0: return [4 /*yield*/, getDBPromise()];
550
- case 1:
551
- db = _a.sent();
552
- transaction = db.transaction(STORE_NAME, 'readonly');
553
- store = transaction.objectStore(STORE_NAME);
554
- request = store.get(key);
555
- return [2 /*return*/, new Promise(function (resolve, reject) {
556
- request.onsuccess = function (event) {
557
- var result = event.target.result;
558
- if (result) {
559
- resolve(result.value);
560
- }
561
- else {
562
- resolve(undefined);
563
- }
564
- };
565
- transaction.onerror = function (event) {
566
- var _a;
567
- reject(ERROR_FACTORY.create("storage-get" /* AppCheckError.STORAGE_GET */, {
568
- originalErrorMessage: (_a = event.target.error) === null || _a === void 0 ? void 0 : _a.message
569
- }));
570
- };
571
- })];
494
+ async function read(key) {
495
+ const db = await getDBPromise();
496
+ const transaction = db.transaction(STORE_NAME, 'readonly');
497
+ const store = transaction.objectStore(STORE_NAME);
498
+ const request = store.get(key);
499
+ return new Promise((resolve, reject) => {
500
+ request.onsuccess = event => {
501
+ const result = event.target.result;
502
+ if (result) {
503
+ resolve(result.value);
572
504
  }
573
- });
505
+ else {
506
+ resolve(undefined);
507
+ }
508
+ };
509
+ transaction.onerror = event => {
510
+ var _a;
511
+ reject(ERROR_FACTORY.create("storage-get" /* AppCheckError.STORAGE_GET */, {
512
+ originalErrorMessage: (_a = event.target.error) === null || _a === void 0 ? void 0 : _a.message
513
+ }));
514
+ };
574
515
  });
575
516
  }
576
517
  function computeKey(app) {
577
- return "".concat(app.options.appId, "-").concat(app.name);
518
+ return `${app.options.appId}-${app.name}`;
578
519
  }
579
520
 
580
521
  /**
@@ -593,7 +534,7 @@ function computeKey(app) {
593
534
  * See the License for the specific language governing permissions and
594
535
  * limitations under the License.
595
536
  */
596
- var logger = new logger$1.Logger('@firebase/app-check');
537
+ const logger = new logger$1.Logger('@firebase/app-check');
597
538
 
598
539
  /**
599
540
  * @license
@@ -614,80 +555,58 @@ var logger = new logger$1.Logger('@firebase/app-check');
614
555
  /**
615
556
  * Always resolves. In case of an error reading from indexeddb, resolve with undefined
616
557
  */
617
- function readTokenFromStorage(app) {
618
- return tslib.__awaiter(this, void 0, void 0, function () {
619
- var token, e_1;
620
- return tslib.__generator(this, function (_a) {
621
- switch (_a.label) {
622
- case 0:
623
- if (!util.isIndexedDBAvailable()) return [3 /*break*/, 5];
624
- token = undefined;
625
- _a.label = 1;
626
- case 1:
627
- _a.trys.push([1, 3, , 4]);
628
- return [4 /*yield*/, readTokenFromIndexedDB(app)];
629
- case 2:
630
- token = _a.sent();
631
- return [3 /*break*/, 4];
632
- case 3:
633
- e_1 = _a.sent();
634
- // swallow the error and return undefined
635
- logger.warn("Failed to read token from IndexedDB. Error: ".concat(e_1));
636
- return [3 /*break*/, 4];
637
- case 4: return [2 /*return*/, token];
638
- case 5: return [2 /*return*/, undefined];
639
- }
640
- });
641
- });
558
+ async function readTokenFromStorage(app) {
559
+ if (util.isIndexedDBAvailable()) {
560
+ let token = undefined;
561
+ try {
562
+ token = await readTokenFromIndexedDB(app);
563
+ }
564
+ catch (e) {
565
+ // swallow the error and return undefined
566
+ logger.warn(`Failed to read token from IndexedDB. Error: ${e}`);
567
+ }
568
+ return token;
569
+ }
570
+ return undefined;
642
571
  }
643
572
  /**
644
573
  * Always resolves. In case of an error writing to indexeddb, print a warning and resolve the promise
645
574
  */
646
575
  function writeTokenToStorage(app, token) {
647
576
  if (util.isIndexedDBAvailable()) {
648
- return writeTokenToIndexedDB(app, token).catch(function (e) {
577
+ return writeTokenToIndexedDB(app, token).catch(e => {
649
578
  // swallow the error and resolve the promise
650
- logger.warn("Failed to write token to IndexedDB. Error: ".concat(e));
579
+ logger.warn(`Failed to write token to IndexedDB. Error: ${e}`);
651
580
  });
652
581
  }
653
582
  return Promise.resolve();
654
583
  }
655
- function readOrCreateDebugTokenFromStorage() {
656
- return tslib.__awaiter(this, void 0, void 0, function () {
657
- var existingDebugToken, newToken;
658
- return tslib.__generator(this, function (_a) {
659
- switch (_a.label) {
660
- case 0:
661
- existingDebugToken = undefined;
662
- _a.label = 1;
663
- case 1:
664
- _a.trys.push([1, 3, , 4]);
665
- return [4 /*yield*/, readDebugTokenFromIndexedDB()];
666
- case 2:
667
- existingDebugToken = _a.sent();
668
- return [3 /*break*/, 4];
669
- case 3:
670
- _a.sent();
671
- return [3 /*break*/, 4];
672
- case 4:
673
- if (!existingDebugToken) {
674
- newToken = util.uuidv4();
675
- // We don't need to block on writing to indexeddb
676
- // In case persistence failed, a new debug token will be generated every time the page is refreshed.
677
- // It renders the debug token useless because you have to manually register(whitelist) the new token in the firebase console again and again.
678
- // If you see this error trying to use debug token, it probably means you are using a browser that doesn't support indexeddb.
679
- // You should switch to a different browser that supports indexeddb
680
- writeDebugTokenToIndexedDB(newToken).catch(function (e) {
681
- return logger.warn("Failed to persist debug token to IndexedDB. Error: ".concat(e));
682
- });
683
- return [2 /*return*/, newToken];
684
- }
685
- else {
686
- return [2 /*return*/, existingDebugToken];
687
- }
688
- }
689
- });
690
- });
584
+ async function readOrCreateDebugTokenFromStorage() {
585
+ /**
586
+ * Theoretically race condition can happen if we read, then write in 2 separate transactions.
587
+ * But it won't happen here, because this function will be called exactly once.
588
+ */
589
+ let existingDebugToken = undefined;
590
+ try {
591
+ existingDebugToken = await readDebugTokenFromIndexedDB();
592
+ }
593
+ catch (_e) {
594
+ // failed to read from indexeddb. We assume there is no existing debug token, and generate a new one.
595
+ }
596
+ if (!existingDebugToken) {
597
+ // create a new debug token
598
+ const newToken = util.uuidv4();
599
+ // We don't need to block on writing to indexeddb
600
+ // In case persistence failed, a new debug token will be generated every time the page is refreshed.
601
+ // It renders the debug token useless because you have to manually register(whitelist) the new token in the firebase console again and again.
602
+ // If you see this error trying to use debug token, it probably means you are using a browser that doesn't support indexeddb.
603
+ // You should switch to a different browser that supports indexeddb
604
+ writeDebugTokenToIndexedDB(newToken).catch(e => logger.warn(`Failed to persist debug token to IndexedDB. Error: ${e}`));
605
+ return newToken;
606
+ }
607
+ else {
608
+ return existingDebugToken;
609
+ }
691
610
  }
692
611
 
693
612
  /**
@@ -707,27 +626,24 @@ function readOrCreateDebugTokenFromStorage() {
707
626
  * limitations under the License.
708
627
  */
709
628
  function isDebugMode() {
710
- var debugState = getDebugState();
629
+ const debugState = getDebugState();
711
630
  return debugState.enabled;
712
631
  }
713
- function getDebugToken() {
714
- return tslib.__awaiter(this, void 0, void 0, function () {
715
- var state;
716
- return tslib.__generator(this, function (_a) {
717
- state = getDebugState();
718
- if (state.enabled && state.token) {
719
- return [2 /*return*/, state.token.promise];
720
- }
721
- else {
722
- // should not happen!
723
- throw Error("\n Can't get debug token in production mode.\n ");
724
- }
725
- });
726
- });
632
+ async function getDebugToken() {
633
+ const state = getDebugState();
634
+ if (state.enabled && state.token) {
635
+ return state.token.promise;
636
+ }
637
+ else {
638
+ // should not happen!
639
+ throw Error(`
640
+ Can't get debug token in production mode.
641
+ `);
642
+ }
727
643
  }
728
644
  function initializeDebugMode() {
729
- var globals = util.getGlobal();
730
- var debugState = getDebugState();
645
+ const globals = util.getGlobal();
646
+ const debugState = getDebugState();
731
647
  // Set to true if this function has been called, whether or not
732
648
  // it enabled debug mode.
733
649
  debugState.initialized = true;
@@ -736,7 +652,7 @@ function initializeDebugMode() {
736
652
  return;
737
653
  }
738
654
  debugState.enabled = true;
739
- var deferredToken = new util.Deferred();
655
+ const deferredToken = new util.Deferred();
740
656
  debugState.token = deferredToken;
741
657
  if (typeof globals.FIREBASE_APPCHECK_DEBUG_TOKEN === 'string') {
742
658
  deferredToken.resolve(globals.FIREBASE_APPCHECK_DEBUG_TOKEN);
@@ -764,7 +680,7 @@ function initializeDebugMode() {
764
680
  */
765
681
  // Initial hardcoded value agreed upon across platforms for initial launch.
766
682
  // Format left open for possible dynamic error values and other fields in the future.
767
- var defaultTokenErrorData = { error: 'UNKNOWN_ERROR' };
683
+ const defaultTokenErrorData = { error: 'UNKNOWN_ERROR' };
768
684
  /**
769
685
  * Stringify and base64 encode token error data.
770
686
  *
@@ -779,200 +695,179 @@ function formatDummyToken(tokenErrorData) {
779
695
  * The result will contain an error field if there is any error.
780
696
  * In case there is an error, the token field in the result will be populated with a dummy value
781
697
  */
782
- function getToken$2(appCheck, forceRefresh) {
783
- if (forceRefresh === void 0) { forceRefresh = false; }
784
- return tslib.__awaiter(this, void 0, void 0, function () {
785
- var app, state, token, error, cachedToken, shouldCallListeners, _a, _b, _c, _d, tokenFromDebugExchange, e_1, interopTokenResult;
786
- return tslib.__generator(this, function (_e) {
787
- switch (_e.label) {
788
- case 0:
789
- app = appCheck.app;
790
- ensureActivated(app);
791
- state = getStateReference(app);
792
- token = state.token;
793
- error = undefined;
794
- /**
795
- * If an invalid token was found in memory, clear token from
796
- * memory and unset the local variable `token`.
797
- */
798
- if (token && !isValid(token)) {
799
- state.token = undefined;
800
- token = undefined;
801
- }
802
- if (!!token) return [3 /*break*/, 4];
803
- return [4 /*yield*/, state.cachedTokenPromise];
804
- case 1:
805
- cachedToken = _e.sent();
806
- if (!cachedToken) return [3 /*break*/, 4];
807
- if (!isValid(cachedToken)) return [3 /*break*/, 2];
808
- token = cachedToken;
809
- return [3 /*break*/, 4];
810
- case 2:
698
+ async function getToken$2(appCheck, forceRefresh = false) {
699
+ const app = appCheck.app;
700
+ ensureActivated(app);
701
+ const state = getStateReference(app);
702
+ /**
703
+ * First check if there is a token in memory from a previous `getToken()` call.
704
+ */
705
+ let token = state.token;
706
+ let error = undefined;
707
+ /**
708
+ * If an invalid token was found in memory, clear token from
709
+ * memory and unset the local variable `token`.
710
+ */
711
+ if (token && !isValid(token)) {
712
+ state.token = undefined;
713
+ token = undefined;
714
+ }
715
+ /**
716
+ * If there is no valid token in memory, try to load token from indexedDB.
717
+ */
718
+ if (!token) {
719
+ // cachedTokenPromise contains the token found in IndexedDB or undefined if not found.
720
+ const cachedToken = await state.cachedTokenPromise;
721
+ if (cachedToken) {
722
+ if (isValid(cachedToken)) {
723
+ token = cachedToken;
724
+ }
725
+ else {
811
726
  // If there was an invalid token in the indexedDB cache, clear it.
812
- return [4 /*yield*/, writeTokenToStorage(app, undefined)];
813
- case 3:
814
- // If there was an invalid token in the indexedDB cache, clear it.
815
- _e.sent();
816
- _e.label = 4;
817
- case 4:
818
- // Return the cached token (from either memory or indexedDB) if it's valid
819
- if (!forceRefresh && token && isValid(token)) {
820
- return [2 /*return*/, {
821
- token: token.token
822
- }];
823
- }
824
- shouldCallListeners = false;
825
- if (!isDebugMode()) return [3 /*break*/, 9];
826
- if (!!state.exchangeTokenPromise) return [3 /*break*/, 6];
827
- _a = state;
828
- _b = exchangeToken;
829
- _c = getExchangeDebugTokenRequest;
830
- _d = [app];
831
- return [4 /*yield*/, getDebugToken()];
832
- case 5:
833
- _a.exchangeTokenPromise = _b.apply(void 0, [_c.apply(void 0, _d.concat([_e.sent()])),
834
- appCheck.heartbeatServiceProvider]).finally(function () {
835
- // Clear promise when settled - either resolved or rejected.
836
- state.exchangeTokenPromise = undefined;
837
- });
838
- shouldCallListeners = true;
839
- _e.label = 6;
840
- case 6: return [4 /*yield*/, state.exchangeTokenPromise];
841
- case 7:
842
- tokenFromDebugExchange = _e.sent();
843
- // Write debug token to indexedDB.
844
- return [4 /*yield*/, writeTokenToStorage(app, tokenFromDebugExchange)];
845
- case 8:
846
- // Write debug token to indexedDB.
847
- _e.sent();
848
- // Write debug token to state.
849
- state.token = tokenFromDebugExchange;
850
- return [2 /*return*/, { token: tokenFromDebugExchange.token }];
851
- case 9:
852
- _e.trys.push([9, 11, , 12]);
853
- // Avoid making another call to the exchange endpoint if one is in flight.
854
- if (!state.exchangeTokenPromise) {
855
- // state.provider is populated in initializeAppCheck()
856
- // ensureActivated() at the top of this function checks that
857
- // initializeAppCheck() has been called.
858
- state.exchangeTokenPromise = state.provider.getToken().finally(function () {
859
- // Clear promise when settled - either resolved or rejected.
860
- state.exchangeTokenPromise = undefined;
861
- });
862
- shouldCallListeners = true;
863
- }
864
- return [4 /*yield*/, getStateReference(app).exchangeTokenPromise];
865
- case 10:
866
- token = _e.sent();
867
- return [3 /*break*/, 12];
868
- case 11:
869
- e_1 = _e.sent();
870
- if (e_1.code === "appCheck/".concat("throttled" /* AppCheckError.THROTTLED */)) {
871
- // Warn if throttled, but do not treat it as an error.
872
- logger.warn(e_1.message);
873
- }
874
- else {
875
- // `getToken()` should never throw, but logging error text to console will aid debugging.
876
- logger.error(e_1);
877
- }
878
- // Always save error to be added to dummy token.
879
- error = e_1;
880
- return [3 /*break*/, 12];
881
- case 12:
882
- if (!!token) return [3 /*break*/, 13];
883
- // If token is undefined, there must be an error.
884
- // Return a dummy token along with the error.
885
- interopTokenResult = makeDummyTokenResult(error);
886
- return [3 /*break*/, 16];
887
- case 13:
888
- if (!error) return [3 /*break*/, 14];
889
- if (isValid(token)) {
890
- // It's also possible a valid token exists, but there's also an error.
891
- // (Such as if the token is almost expired, tries to refresh, and
892
- // the exchange request fails.)
893
- // We add a special error property here so that the refresher will
894
- // count this as a failed attempt and use the backoff instead of
895
- // retrying repeatedly with no delay, but any 3P listeners will not
896
- // be hindered in getting the still-valid token.
897
- interopTokenResult = {
898
- token: token.token,
899
- internalError: error
900
- };
901
- }
902
- else {
903
- // No invalid tokens should make it to this step. Memory and cached tokens
904
- // are checked. Other tokens are from fresh exchanges. But just in case.
905
- interopTokenResult = makeDummyTokenResult(error);
906
- }
907
- return [3 /*break*/, 16];
908
- case 14:
909
- interopTokenResult = {
910
- token: token.token
911
- };
912
- // write the new token to the memory state as well as the persistent storage.
913
- // Only do it if we got a valid new token
914
- state.token = token;
915
- return [4 /*yield*/, writeTokenToStorage(app, token)];
916
- case 15:
917
- _e.sent();
918
- _e.label = 16;
919
- case 16:
920
- if (shouldCallListeners) {
921
- notifyTokenListeners(app, interopTokenResult);
922
- }
923
- return [2 /*return*/, interopTokenResult];
727
+ await writeTokenToStorage(app, undefined);
924
728
  }
925
- });
926
- });
729
+ }
730
+ }
731
+ // Return the cached token (from either memory or indexedDB) if it's valid
732
+ if (!forceRefresh && token && isValid(token)) {
733
+ return {
734
+ token: token.token
735
+ };
736
+ }
737
+ // Only set to true if this `getToken()` call is making the actual
738
+ // REST call to the exchange endpoint, versus waiting for an already
739
+ // in-flight call (see debug and regular exchange endpoint paths below)
740
+ let shouldCallListeners = false;
741
+ /**
742
+ * DEBUG MODE
743
+ * If debug mode is set, and there is no cached token, fetch a new App
744
+ * Check token using the debug token, and return it directly.
745
+ */
746
+ if (isDebugMode()) {
747
+ // Avoid making another call to the exchange endpoint if one is in flight.
748
+ if (!state.exchangeTokenPromise) {
749
+ state.exchangeTokenPromise = exchangeToken(getExchangeDebugTokenRequest(app, await getDebugToken()), appCheck.heartbeatServiceProvider).finally(() => {
750
+ // Clear promise when settled - either resolved or rejected.
751
+ state.exchangeTokenPromise = undefined;
752
+ });
753
+ shouldCallListeners = true;
754
+ }
755
+ const tokenFromDebugExchange = await state.exchangeTokenPromise;
756
+ // Write debug token to indexedDB.
757
+ await writeTokenToStorage(app, tokenFromDebugExchange);
758
+ // Write debug token to state.
759
+ state.token = tokenFromDebugExchange;
760
+ return { token: tokenFromDebugExchange.token };
761
+ }
762
+ /**
763
+ * There are no valid tokens in memory or indexedDB and we are not in
764
+ * debug mode.
765
+ * Request a new token from the exchange endpoint.
766
+ */
767
+ try {
768
+ // Avoid making another call to the exchange endpoint if one is in flight.
769
+ if (!state.exchangeTokenPromise) {
770
+ // state.provider is populated in initializeAppCheck()
771
+ // ensureActivated() at the top of this function checks that
772
+ // initializeAppCheck() has been called.
773
+ state.exchangeTokenPromise = state.provider.getToken().finally(() => {
774
+ // Clear promise when settled - either resolved or rejected.
775
+ state.exchangeTokenPromise = undefined;
776
+ });
777
+ shouldCallListeners = true;
778
+ }
779
+ token = await getStateReference(app).exchangeTokenPromise;
780
+ }
781
+ catch (e) {
782
+ if (e.code === `appCheck/${"throttled" /* AppCheckError.THROTTLED */}`) {
783
+ // Warn if throttled, but do not treat it as an error.
784
+ logger.warn(e.message);
785
+ }
786
+ else {
787
+ // `getToken()` should never throw, but logging error text to console will aid debugging.
788
+ logger.error(e);
789
+ }
790
+ // Always save error to be added to dummy token.
791
+ error = e;
792
+ }
793
+ let interopTokenResult;
794
+ if (!token) {
795
+ // If token is undefined, there must be an error.
796
+ // Return a dummy token along with the error.
797
+ interopTokenResult = makeDummyTokenResult(error);
798
+ }
799
+ else if (error) {
800
+ if (isValid(token)) {
801
+ // It's also possible a valid token exists, but there's also an error.
802
+ // (Such as if the token is almost expired, tries to refresh, and
803
+ // the exchange request fails.)
804
+ // We add a special error property here so that the refresher will
805
+ // count this as a failed attempt and use the backoff instead of
806
+ // retrying repeatedly with no delay, but any 3P listeners will not
807
+ // be hindered in getting the still-valid token.
808
+ interopTokenResult = {
809
+ token: token.token,
810
+ internalError: error
811
+ };
812
+ }
813
+ else {
814
+ // No invalid tokens should make it to this step. Memory and cached tokens
815
+ // are checked. Other tokens are from fresh exchanges. But just in case.
816
+ interopTokenResult = makeDummyTokenResult(error);
817
+ }
818
+ }
819
+ else {
820
+ interopTokenResult = {
821
+ token: token.token
822
+ };
823
+ // write the new token to the memory state as well as the persistent storage.
824
+ // Only do it if we got a valid new token
825
+ state.token = token;
826
+ await writeTokenToStorage(app, token);
827
+ }
828
+ if (shouldCallListeners) {
829
+ notifyTokenListeners(app, interopTokenResult);
830
+ }
831
+ return interopTokenResult;
927
832
  }
928
833
  /**
929
834
  * Internal API for limited use tokens. Skips all FAC state and simply calls
930
835
  * the underlying provider.
931
836
  */
932
- function getLimitedUseToken$1(appCheck) {
933
- return tslib.__awaiter(this, void 0, void 0, function () {
934
- var app, provider, debugToken, token, token;
935
- return tslib.__generator(this, function (_a) {
936
- switch (_a.label) {
937
- case 0:
938
- app = appCheck.app;
939
- ensureActivated(app);
940
- provider = getStateReference(app).provider;
941
- if (!isDebugMode()) return [3 /*break*/, 3];
942
- return [4 /*yield*/, getDebugToken()];
943
- case 1:
944
- debugToken = _a.sent();
945
- return [4 /*yield*/, exchangeToken(getExchangeDebugTokenRequest(app, debugToken), appCheck.heartbeatServiceProvider)];
946
- case 2:
947
- token = (_a.sent()).token;
948
- return [2 /*return*/, { token: token }];
949
- case 3: return [4 /*yield*/, provider.getToken()];
950
- case 4:
951
- token = (_a.sent()).token;
952
- return [2 /*return*/, { token: token }];
953
- }
954
- });
955
- });
837
+ async function getLimitedUseToken$1(appCheck) {
838
+ const app = appCheck.app;
839
+ ensureActivated(app);
840
+ const { provider } = getStateReference(app);
841
+ if (isDebugMode()) {
842
+ const debugToken = await getDebugToken();
843
+ const { token } = await exchangeToken(getExchangeDebugTokenRequest(app, debugToken), appCheck.heartbeatServiceProvider);
844
+ return { token };
845
+ }
846
+ else {
847
+ // provider is definitely valid since we ensure AppCheck was activated
848
+ const { token } = await provider.getToken();
849
+ return { token };
850
+ }
956
851
  }
957
852
  function addTokenListener(appCheck, type, listener, onError) {
958
- var app = appCheck.app;
959
- var state = getStateReference(app);
960
- var tokenObserver = {
853
+ const { app } = appCheck;
854
+ const state = getStateReference(app);
855
+ const tokenObserver = {
961
856
  next: listener,
962
857
  error: onError,
963
- type: type
858
+ type
964
859
  };
965
- state.tokenObservers = tslib.__spreadArray(tslib.__spreadArray([], state.tokenObservers, true), [tokenObserver], false);
860
+ state.tokenObservers = [...state.tokenObservers, tokenObserver];
966
861
  // Invoke the listener async immediately if there is a valid token
967
862
  // in memory.
968
863
  if (state.token && isValid(state.token)) {
969
- var validToken_1 = state.token;
864
+ const validToken = state.token;
970
865
  Promise.resolve()
971
- .then(function () {
972
- listener({ token: validToken_1.token });
866
+ .then(() => {
867
+ listener({ token: validToken.token });
973
868
  initTokenRefresher(appCheck);
974
869
  })
975
- .catch(function () {
870
+ .catch(() => {
976
871
  /* we don't care about exceptions thrown in listeners */
977
872
  });
978
873
  }
@@ -986,11 +881,11 @@ function addTokenListener(appCheck, type, listener, onError) {
986
881
  * listeners that exist when it resolves.
987
882
  */
988
883
  // state.cachedTokenPromise is always populated in `activate()`.
989
- void state.cachedTokenPromise.then(function () { return initTokenRefresher(appCheck); });
884
+ void state.cachedTokenPromise.then(() => initTokenRefresher(appCheck));
990
885
  }
991
886
  function removeTokenListener(app, listener) {
992
- var state = getStateReference(app);
993
- var newObservers = state.tokenObservers.filter(function (tokenObserver) { return tokenObserver.next !== listener; });
887
+ const state = getStateReference(app);
888
+ const newObservers = state.tokenObservers.filter(tokenObserver => tokenObserver.next !== listener);
994
889
  if (newObservers.length === 0 &&
995
890
  state.tokenRefresher &&
996
891
  state.tokenRefresher.isRunning()) {
@@ -1002,11 +897,11 @@ function removeTokenListener(app, listener) {
1002
897
  * Logic to create and start refresher as needed.
1003
898
  */
1004
899
  function initTokenRefresher(appCheck) {
1005
- var app = appCheck.app;
1006
- var state = getStateReference(app);
900
+ const { app } = appCheck;
901
+ const state = getStateReference(app);
1007
902
  // Create the refresher but don't start it if `isTokenAutoRefreshEnabled`
1008
903
  // is not true.
1009
- var refresher = state.tokenRefresher;
904
+ let refresher = state.tokenRefresher;
1010
905
  if (!refresher) {
1011
906
  refresher = createTokenRefresher(appCheck);
1012
907
  state.tokenRefresher = refresher;
@@ -1016,60 +911,51 @@ function initTokenRefresher(appCheck) {
1016
911
  }
1017
912
  }
1018
913
  function createTokenRefresher(appCheck) {
1019
- var _this = this;
1020
- var app = appCheck.app;
914
+ const { app } = appCheck;
1021
915
  return new Refresher(
1022
916
  // Keep in mind when this fails for any reason other than the ones
1023
917
  // for which we should retry, it will effectively stop the proactive refresh.
1024
- function () { return tslib.__awaiter(_this, void 0, void 0, function () {
1025
- var state, result;
1026
- return tslib.__generator(this, function (_a) {
1027
- switch (_a.label) {
1028
- case 0:
1029
- state = getStateReference(app);
1030
- if (!!state.token) return [3 /*break*/, 2];
1031
- return [4 /*yield*/, getToken$2(appCheck)];
1032
- case 1:
1033
- result = _a.sent();
1034
- return [3 /*break*/, 4];
1035
- case 2: return [4 /*yield*/, getToken$2(appCheck, true)];
1036
- case 3:
1037
- result = _a.sent();
1038
- _a.label = 4;
1039
- case 4:
1040
- /**
1041
- * getToken() always resolves. In case the result has an error field defined, it means
1042
- * the operation failed, and we should retry.
1043
- */
1044
- if (result.error) {
1045
- throw result.error;
1046
- }
1047
- /**
1048
- * A special `internalError` field reflects that there was an error
1049
- * getting a new token from the exchange endpoint, but there's still a
1050
- * previous token that's valid for now and this should be passed to 2P/3P
1051
- * requests for a token. But we want this callback (`this.operation` in
1052
- * `Refresher`) to throw in order to kick off the Refresher's retry
1053
- * backoff. (Setting `hasSucceeded` to false.)
1054
- */
1055
- if (result.internalError) {
1056
- throw result.internalError;
1057
- }
1058
- return [2 /*return*/];
1059
- }
1060
- });
1061
- }); }, function () {
918
+ async () => {
919
+ const state = getStateReference(app);
920
+ // If there is no token, we will try to load it from storage and use it
921
+ // If there is a token, we force refresh it because we know it's going to expire soon
922
+ let result;
923
+ if (!state.token) {
924
+ result = await getToken$2(appCheck);
925
+ }
926
+ else {
927
+ result = await getToken$2(appCheck, true);
928
+ }
929
+ /**
930
+ * getToken() always resolves. In case the result has an error field defined, it means
931
+ * the operation failed, and we should retry.
932
+ */
933
+ if (result.error) {
934
+ throw result.error;
935
+ }
936
+ /**
937
+ * A special `internalError` field reflects that there was an error
938
+ * getting a new token from the exchange endpoint, but there's still a
939
+ * previous token that's valid for now and this should be passed to 2P/3P
940
+ * requests for a token. But we want this callback (`this.operation` in
941
+ * `Refresher`) to throw in order to kick off the Refresher's retry
942
+ * backoff. (Setting `hasSucceeded` to false.)
943
+ */
944
+ if (result.internalError) {
945
+ throw result.internalError;
946
+ }
947
+ }, () => {
1062
948
  return true;
1063
- }, function () {
1064
- var state = getStateReference(app);
949
+ }, () => {
950
+ const state = getStateReference(app);
1065
951
  if (state.token) {
1066
952
  // issuedAtTime + (50% * total TTL) + 5 minutes
1067
- var nextRefreshTimeMillis = state.token.issuedAtTimeMillis +
953
+ let nextRefreshTimeMillis = state.token.issuedAtTimeMillis +
1068
954
  (state.token.expireTimeMillis - state.token.issuedAtTimeMillis) *
1069
955
  0.5 +
1070
956
  5 * 60 * 1000;
1071
957
  // Do not allow refresh time to be past (expireTime - 5 minutes)
1072
- var latestAllowableRefresh = state.token.expireTimeMillis - 5 * 60 * 1000;
958
+ const latestAllowableRefresh = state.token.expireTimeMillis - 5 * 60 * 1000;
1073
959
  nextRefreshTimeMillis = Math.min(nextRefreshTimeMillis, latestAllowableRefresh);
1074
960
  return Math.max(0, nextRefreshTimeMillis - Date.now());
1075
961
  }
@@ -1079,9 +965,8 @@ function createTokenRefresher(appCheck) {
1079
965
  }, TOKEN_REFRESH_TIME.RETRIAL_MIN_WAIT, TOKEN_REFRESH_TIME.RETRIAL_MAX_WAIT);
1080
966
  }
1081
967
  function notifyTokenListeners(app, token) {
1082
- var observers = getStateReference(app).tokenObservers;
1083
- for (var _i = 0, observers_1 = observers; _i < observers_1.length; _i++) {
1084
- var observer = observers_1[_i];
968
+ const observers = getStateReference(app).tokenObservers;
969
+ for (const observer of observers) {
1085
970
  try {
1086
971
  if (observer.type === "EXTERNAL" /* ListenerType.EXTERNAL */ && token.error != null) {
1087
972
  // If this listener was added by a 3P call, send any token error to
@@ -1107,7 +992,7 @@ function isValid(token) {
1107
992
  function makeDummyTokenResult(error) {
1108
993
  return {
1109
994
  token: formatDummyToken(defaultTokenErrorData),
1110
- error: error
995
+ error
1111
996
  };
1112
997
  }
1113
998
 
@@ -1130,37 +1015,33 @@ function makeDummyTokenResult(error) {
1130
1015
  /**
1131
1016
  * AppCheck Service class.
1132
1017
  */
1133
- var AppCheckService = /** @class */ (function () {
1134
- function AppCheckService(app, heartbeatServiceProvider) {
1018
+ class AppCheckService {
1019
+ constructor(app, heartbeatServiceProvider) {
1135
1020
  this.app = app;
1136
1021
  this.heartbeatServiceProvider = heartbeatServiceProvider;
1137
1022
  }
1138
- AppCheckService.prototype._delete = function () {
1139
- var tokenObservers = getStateReference(this.app).tokenObservers;
1140
- for (var _i = 0, tokenObservers_1 = tokenObservers; _i < tokenObservers_1.length; _i++) {
1141
- var tokenObserver = tokenObservers_1[_i];
1023
+ _delete() {
1024
+ const { tokenObservers } = getStateReference(this.app);
1025
+ for (const tokenObserver of tokenObservers) {
1142
1026
  removeTokenListener(this.app, tokenObserver.next);
1143
1027
  }
1144
1028
  return Promise.resolve();
1145
- };
1146
- return AppCheckService;
1147
- }());
1029
+ }
1030
+ }
1148
1031
  function factory(app, heartbeatServiceProvider) {
1149
1032
  return new AppCheckService(app, heartbeatServiceProvider);
1150
1033
  }
1151
1034
  function internalFactory(appCheck) {
1152
1035
  return {
1153
- getToken: function (forceRefresh) { return getToken$2(appCheck, forceRefresh); },
1154
- getLimitedUseToken: function () { return getLimitedUseToken$1(appCheck); },
1155
- addTokenListener: function (listener) {
1156
- return addTokenListener(appCheck, "INTERNAL" /* ListenerType.INTERNAL */, listener);
1157
- },
1158
- removeTokenListener: function (listener) { return removeTokenListener(appCheck.app, listener); }
1036
+ getToken: forceRefresh => getToken$2(appCheck, forceRefresh),
1037
+ getLimitedUseToken: () => getLimitedUseToken$1(appCheck),
1038
+ addTokenListener: listener => addTokenListener(appCheck, "INTERNAL" /* ListenerType.INTERNAL */, listener),
1039
+ removeTokenListener: listener => removeTokenListener(appCheck.app, listener)
1159
1040
  };
1160
1041
  }
1161
1042
 
1162
- var name = "@firebase/app-check";
1163
- var version = "0.8.8";
1043
+ const name = "@firebase/app-check";
1044
+ const version = "0.8.9";
1164
1045
 
1165
1046
  /**
1166
1047
  * @license
@@ -1178,17 +1059,17 @@ var version = "0.8.8";
1178
1059
  * See the License for the specific language governing permissions and
1179
1060
  * limitations under the License.
1180
1061
  */
1181
- var RECAPTCHA_URL = 'https://www.google.com/recaptcha/api.js';
1182
- var RECAPTCHA_ENTERPRISE_URL = 'https://www.google.com/recaptcha/enterprise.js';
1062
+ const RECAPTCHA_URL = 'https://www.google.com/recaptcha/api.js';
1063
+ const RECAPTCHA_ENTERPRISE_URL = 'https://www.google.com/recaptcha/enterprise.js';
1183
1064
  function initializeV3(app, siteKey) {
1184
- var initialized = new util.Deferred();
1185
- var state = getStateReference(app);
1186
- state.reCAPTCHAState = { initialized: initialized };
1187
- var divId = makeDiv(app);
1188
- var grecaptcha = getRecaptcha(false);
1065
+ const initialized = new util.Deferred();
1066
+ const state = getStateReference(app);
1067
+ state.reCAPTCHAState = { initialized };
1068
+ const divId = makeDiv(app);
1069
+ const grecaptcha = getRecaptcha(false);
1189
1070
  if (!grecaptcha) {
1190
- loadReCAPTCHAV3Script(function () {
1191
- var grecaptcha = getRecaptcha(false);
1071
+ loadReCAPTCHAV3Script(() => {
1072
+ const grecaptcha = getRecaptcha(false);
1192
1073
  if (!grecaptcha) {
1193
1074
  // it shouldn't happen.
1194
1075
  throw new Error('no recaptcha');
@@ -1202,14 +1083,14 @@ function initializeV3(app, siteKey) {
1202
1083
  return initialized.promise;
1203
1084
  }
1204
1085
  function initializeEnterprise(app, siteKey) {
1205
- var initialized = new util.Deferred();
1206
- var state = getStateReference(app);
1207
- state.reCAPTCHAState = { initialized: initialized };
1208
- var divId = makeDiv(app);
1209
- var grecaptcha = getRecaptcha(true);
1086
+ const initialized = new util.Deferred();
1087
+ const state = getStateReference(app);
1088
+ state.reCAPTCHAState = { initialized };
1089
+ const divId = makeDiv(app);
1090
+ const grecaptcha = getRecaptcha(true);
1210
1091
  if (!grecaptcha) {
1211
- loadReCAPTCHAEnterpriseScript(function () {
1212
- var grecaptcha = getRecaptcha(true);
1092
+ loadReCAPTCHAEnterpriseScript(() => {
1093
+ const grecaptcha = getRecaptcha(true);
1213
1094
  if (!grecaptcha) {
1214
1095
  // it shouldn't happen.
1215
1096
  throw new Error('no recaptcha');
@@ -1227,7 +1108,7 @@ function initializeEnterprise(app, siteKey) {
1227
1108
  * the grecaptcha.ready() event fires.
1228
1109
  */
1229
1110
  function queueWidgetRender(app, siteKey, grecaptcha, container, initialized) {
1230
- grecaptcha.ready(function () {
1111
+ grecaptcha.ready(() => {
1231
1112
  // Invisible widgets allow us to set a different siteKey for each widget,
1232
1113
  // so we use them to support multiple apps
1233
1114
  renderInvisibleWidget(app, siteKey, grecaptcha, container);
@@ -1238,36 +1119,27 @@ function queueWidgetRender(app, siteKey, grecaptcha, container, initialized) {
1238
1119
  * Add invisible div to page.
1239
1120
  */
1240
1121
  function makeDiv(app) {
1241
- var divId = "fire_app_check_".concat(app.name);
1242
- var invisibleDiv = document.createElement('div');
1122
+ const divId = `fire_app_check_${app.name}`;
1123
+ const invisibleDiv = document.createElement('div');
1243
1124
  invisibleDiv.id = divId;
1244
1125
  invisibleDiv.style.display = 'none';
1245
1126
  document.body.appendChild(invisibleDiv);
1246
1127
  return divId;
1247
1128
  }
1248
- function getToken$1(app) {
1249
- return tslib.__awaiter(this, void 0, void 0, function () {
1250
- var reCAPTCHAState, recaptcha;
1251
- return tslib.__generator(this, function (_a) {
1252
- switch (_a.label) {
1253
- case 0:
1254
- ensureActivated(app);
1255
- reCAPTCHAState = getStateReference(app).reCAPTCHAState;
1256
- return [4 /*yield*/, reCAPTCHAState.initialized.promise];
1257
- case 1:
1258
- recaptcha = _a.sent();
1259
- return [2 /*return*/, new Promise(function (resolve, _reject) {
1260
- // Updated after initialization is complete.
1261
- var reCAPTCHAState = getStateReference(app).reCAPTCHAState;
1262
- recaptcha.ready(function () {
1263
- resolve(
1264
- // widgetId is guaranteed to be available if reCAPTCHAState.initialized.promise resolved.
1265
- recaptcha.execute(reCAPTCHAState.widgetId, {
1266
- action: 'fire_app_check'
1267
- }));
1268
- });
1269
- })];
1270
- }
1129
+ async function getToken$1(app) {
1130
+ ensureActivated(app);
1131
+ // ensureActivated() guarantees that reCAPTCHAState is set
1132
+ const reCAPTCHAState = getStateReference(app).reCAPTCHAState;
1133
+ const recaptcha = await reCAPTCHAState.initialized.promise;
1134
+ return new Promise((resolve, _reject) => {
1135
+ // Updated after initialization is complete.
1136
+ const reCAPTCHAState = getStateReference(app).reCAPTCHAState;
1137
+ recaptcha.ready(() => {
1138
+ resolve(
1139
+ // widgetId is guaranteed to be available if reCAPTCHAState.initialized.promise resolved.
1140
+ recaptcha.execute(reCAPTCHAState.widgetId, {
1141
+ action: 'fire_app_check'
1142
+ }));
1271
1143
  });
1272
1144
  });
1273
1145
  }
@@ -1277,30 +1149,30 @@ function getToken$1(app) {
1277
1149
  * @param container - Id of a HTML element.
1278
1150
  */
1279
1151
  function renderInvisibleWidget(app, siteKey, grecaptcha, container) {
1280
- var widgetId = grecaptcha.render(container, {
1152
+ const widgetId = grecaptcha.render(container, {
1281
1153
  sitekey: siteKey,
1282
1154
  size: 'invisible',
1283
1155
  // Success callback - set state
1284
- callback: function () {
1156
+ callback: () => {
1285
1157
  getStateReference(app).reCAPTCHAState.succeeded = true;
1286
1158
  },
1287
1159
  // Failure callback - set state
1288
- 'error-callback': function () {
1160
+ 'error-callback': () => {
1289
1161
  getStateReference(app).reCAPTCHAState.succeeded = false;
1290
1162
  }
1291
1163
  });
1292
- var state = getStateReference(app);
1293
- state.reCAPTCHAState = tslib.__assign(tslib.__assign({}, state.reCAPTCHAState), { // state.reCAPTCHAState is set in the initialize()
1294
- widgetId: widgetId });
1164
+ const state = getStateReference(app);
1165
+ state.reCAPTCHAState = Object.assign(Object.assign({}, state.reCAPTCHAState), { // state.reCAPTCHAState is set in the initialize()
1166
+ widgetId });
1295
1167
  }
1296
1168
  function loadReCAPTCHAV3Script(onload) {
1297
- var script = document.createElement('script');
1169
+ const script = document.createElement('script');
1298
1170
  script.src = RECAPTCHA_URL;
1299
1171
  script.onload = onload;
1300
1172
  document.head.appendChild(script);
1301
1173
  }
1302
1174
  function loadReCAPTCHAEnterpriseScript(onload) {
1303
- var script = document.createElement('script');
1175
+ const script = document.createElement('script');
1304
1176
  script.src = RECAPTCHA_ENTERPRISE_URL;
1305
1177
  script.onload = onload;
1306
1178
  document.head.appendChild(script);
@@ -1328,12 +1200,12 @@ function loadReCAPTCHAEnterpriseScript(onload) {
1328
1200
  *
1329
1201
  * @public
1330
1202
  */
1331
- var ReCaptchaV3Provider = /** @class */ (function () {
1203
+ class ReCaptchaV3Provider {
1332
1204
  /**
1333
1205
  * Create a ReCaptchaV3Provider instance.
1334
1206
  * @param siteKey - ReCAPTCHA V3 siteKey.
1335
1207
  */
1336
- function ReCaptchaV3Provider(_siteKey) {
1208
+ constructor(_siteKey) {
1337
1209
  this._siteKey = _siteKey;
1338
1210
  /**
1339
1211
  * Throttle requests on certain error codes to prevent too many retries
@@ -1345,86 +1217,73 @@ var ReCaptchaV3Provider = /** @class */ (function () {
1345
1217
  * Returns an App Check token.
1346
1218
  * @internal
1347
1219
  */
1348
- ReCaptchaV3Provider.prototype.getToken = function () {
1220
+ async getToken() {
1349
1221
  var _a, _b, _c;
1350
- return tslib.__awaiter(this, void 0, void 0, function () {
1351
- var attestedClaimsToken, result, e_1;
1352
- return tslib.__generator(this, function (_d) {
1353
- switch (_d.label) {
1354
- case 0:
1355
- throwIfThrottled(this._throttleData);
1356
- return [4 /*yield*/, getToken$1(this._app).catch(function (_e) {
1357
- // reCaptcha.execute() throws null which is not very descriptive.
1358
- throw ERROR_FACTORY.create("recaptcha-error" /* AppCheckError.RECAPTCHA_ERROR */);
1359
- })];
1360
- case 1:
1361
- attestedClaimsToken = _d.sent();
1362
- // Check if a failure state was set by the recaptcha "error-callback".
1363
- if (!((_a = getStateReference(this._app).reCAPTCHAState) === null || _a === void 0 ? void 0 : _a.succeeded)) {
1364
- throw ERROR_FACTORY.create("recaptcha-error" /* AppCheckError.RECAPTCHA_ERROR */);
1365
- }
1366
- _d.label = 2;
1367
- case 2:
1368
- _d.trys.push([2, 4, , 5]);
1369
- return [4 /*yield*/, exchangeToken(getExchangeRecaptchaV3TokenRequest(this._app, attestedClaimsToken), this._heartbeatServiceProvider)];
1370
- case 3:
1371
- result = _d.sent();
1372
- return [3 /*break*/, 5];
1373
- case 4:
1374
- e_1 = _d.sent();
1375
- if ((_b = e_1.code) === null || _b === void 0 ? void 0 : _b.includes("fetch-status-error" /* AppCheckError.FETCH_STATUS_ERROR */)) {
1376
- this._throttleData = setBackoff(Number((_c = e_1.customData) === null || _c === void 0 ? void 0 : _c.httpStatus), this._throttleData);
1377
- throw ERROR_FACTORY.create("throttled" /* AppCheckError.THROTTLED */, {
1378
- time: getDurationString(this._throttleData.allowRequestsAfter - Date.now()),
1379
- httpStatus: this._throttleData.httpStatus
1380
- });
1381
- }
1382
- else {
1383
- throw e_1;
1384
- }
1385
- case 5:
1386
- // If successful, clear throttle data.
1387
- this._throttleData = null;
1388
- return [2 /*return*/, result];
1389
- }
1390
- });
1222
+ throwIfThrottled(this._throttleData);
1223
+ // Top-level `getToken()` has already checked that App Check is initialized
1224
+ // and therefore this._app and this._heartbeatServiceProvider are available.
1225
+ const attestedClaimsToken = await getToken$1(this._app).catch(_e => {
1226
+ // reCaptcha.execute() throws null which is not very descriptive.
1227
+ throw ERROR_FACTORY.create("recaptcha-error" /* AppCheckError.RECAPTCHA_ERROR */);
1391
1228
  });
1392
- };
1229
+ // Check if a failure state was set by the recaptcha "error-callback".
1230
+ if (!((_a = getStateReference(this._app).reCAPTCHAState) === null || _a === void 0 ? void 0 : _a.succeeded)) {
1231
+ throw ERROR_FACTORY.create("recaptcha-error" /* AppCheckError.RECAPTCHA_ERROR */);
1232
+ }
1233
+ let result;
1234
+ try {
1235
+ result = await exchangeToken(getExchangeRecaptchaV3TokenRequest(this._app, attestedClaimsToken), this._heartbeatServiceProvider);
1236
+ }
1237
+ catch (e) {
1238
+ if ((_b = e.code) === null || _b === void 0 ? void 0 : _b.includes("fetch-status-error" /* AppCheckError.FETCH_STATUS_ERROR */)) {
1239
+ this._throttleData = setBackoff(Number((_c = e.customData) === null || _c === void 0 ? void 0 : _c.httpStatus), this._throttleData);
1240
+ throw ERROR_FACTORY.create("throttled" /* AppCheckError.THROTTLED */, {
1241
+ time: getDurationString(this._throttleData.allowRequestsAfter - Date.now()),
1242
+ httpStatus: this._throttleData.httpStatus
1243
+ });
1244
+ }
1245
+ else {
1246
+ throw e;
1247
+ }
1248
+ }
1249
+ // If successful, clear throttle data.
1250
+ this._throttleData = null;
1251
+ return result;
1252
+ }
1393
1253
  /**
1394
1254
  * @internal
1395
1255
  */
1396
- ReCaptchaV3Provider.prototype.initialize = function (app$1) {
1256
+ initialize(app$1) {
1397
1257
  this._app = app$1;
1398
1258
  this._heartbeatServiceProvider = app._getProvider(app$1, 'heartbeat');
1399
- initializeV3(app$1, this._siteKey).catch(function () {
1259
+ initializeV3(app$1, this._siteKey).catch(() => {
1400
1260
  /* we don't care about the initialization result */
1401
1261
  });
1402
- };
1262
+ }
1403
1263
  /**
1404
1264
  * @internal
1405
1265
  */
1406
- ReCaptchaV3Provider.prototype.isEqual = function (otherProvider) {
1266
+ isEqual(otherProvider) {
1407
1267
  if (otherProvider instanceof ReCaptchaV3Provider) {
1408
1268
  return this._siteKey === otherProvider._siteKey;
1409
1269
  }
1410
1270
  else {
1411
1271
  return false;
1412
1272
  }
1413
- };
1414
- return ReCaptchaV3Provider;
1415
- }());
1273
+ }
1274
+ }
1416
1275
  /**
1417
1276
  * App Check provider that can obtain a reCAPTCHA Enterprise token and exchange it
1418
1277
  * for an App Check token.
1419
1278
  *
1420
1279
  * @public
1421
1280
  */
1422
- var ReCaptchaEnterpriseProvider = /** @class */ (function () {
1281
+ class ReCaptchaEnterpriseProvider {
1423
1282
  /**
1424
1283
  * Create a ReCaptchaEnterpriseProvider instance.
1425
1284
  * @param siteKey - reCAPTCHA Enterprise score-based site key.
1426
1285
  */
1427
- function ReCaptchaEnterpriseProvider(_siteKey) {
1286
+ constructor(_siteKey) {
1428
1287
  this._siteKey = _siteKey;
1429
1288
  /**
1430
1289
  * Throttle requests on certain error codes to prevent too many retries
@@ -1436,114 +1295,97 @@ var ReCaptchaEnterpriseProvider = /** @class */ (function () {
1436
1295
  * Returns an App Check token.
1437
1296
  * @internal
1438
1297
  */
1439
- ReCaptchaEnterpriseProvider.prototype.getToken = function () {
1298
+ async getToken() {
1440
1299
  var _a, _b, _c;
1441
- return tslib.__awaiter(this, void 0, void 0, function () {
1442
- var attestedClaimsToken, result, e_2;
1443
- return tslib.__generator(this, function (_d) {
1444
- switch (_d.label) {
1445
- case 0:
1446
- throwIfThrottled(this._throttleData);
1447
- return [4 /*yield*/, getToken$1(this._app).catch(function (_e) {
1448
- // reCaptcha.execute() throws null which is not very descriptive.
1449
- throw ERROR_FACTORY.create("recaptcha-error" /* AppCheckError.RECAPTCHA_ERROR */);
1450
- })];
1451
- case 1:
1452
- attestedClaimsToken = _d.sent();
1453
- // Check if a failure state was set by the recaptcha "error-callback".
1454
- if (!((_a = getStateReference(this._app).reCAPTCHAState) === null || _a === void 0 ? void 0 : _a.succeeded)) {
1455
- throw ERROR_FACTORY.create("recaptcha-error" /* AppCheckError.RECAPTCHA_ERROR */);
1456
- }
1457
- _d.label = 2;
1458
- case 2:
1459
- _d.trys.push([2, 4, , 5]);
1460
- return [4 /*yield*/, exchangeToken(getExchangeRecaptchaEnterpriseTokenRequest(this._app, attestedClaimsToken), this._heartbeatServiceProvider)];
1461
- case 3:
1462
- result = _d.sent();
1463
- return [3 /*break*/, 5];
1464
- case 4:
1465
- e_2 = _d.sent();
1466
- if ((_b = e_2.code) === null || _b === void 0 ? void 0 : _b.includes("fetch-status-error" /* AppCheckError.FETCH_STATUS_ERROR */)) {
1467
- this._throttleData = setBackoff(Number((_c = e_2.customData) === null || _c === void 0 ? void 0 : _c.httpStatus), this._throttleData);
1468
- throw ERROR_FACTORY.create("throttled" /* AppCheckError.THROTTLED */, {
1469
- time: getDurationString(this._throttleData.allowRequestsAfter - Date.now()),
1470
- httpStatus: this._throttleData.httpStatus
1471
- });
1472
- }
1473
- else {
1474
- throw e_2;
1475
- }
1476
- case 5:
1477
- // If successful, clear throttle data.
1478
- this._throttleData = null;
1479
- return [2 /*return*/, result];
1480
- }
1481
- });
1300
+ throwIfThrottled(this._throttleData);
1301
+ // Top-level `getToken()` has already checked that App Check is initialized
1302
+ // and therefore this._app and this._heartbeatServiceProvider are available.
1303
+ const attestedClaimsToken = await getToken$1(this._app).catch(_e => {
1304
+ // reCaptcha.execute() throws null which is not very descriptive.
1305
+ throw ERROR_FACTORY.create("recaptcha-error" /* AppCheckError.RECAPTCHA_ERROR */);
1482
1306
  });
1483
- };
1307
+ // Check if a failure state was set by the recaptcha "error-callback".
1308
+ if (!((_a = getStateReference(this._app).reCAPTCHAState) === null || _a === void 0 ? void 0 : _a.succeeded)) {
1309
+ throw ERROR_FACTORY.create("recaptcha-error" /* AppCheckError.RECAPTCHA_ERROR */);
1310
+ }
1311
+ let result;
1312
+ try {
1313
+ result = await exchangeToken(getExchangeRecaptchaEnterpriseTokenRequest(this._app, attestedClaimsToken), this._heartbeatServiceProvider);
1314
+ }
1315
+ catch (e) {
1316
+ if ((_b = e.code) === null || _b === void 0 ? void 0 : _b.includes("fetch-status-error" /* AppCheckError.FETCH_STATUS_ERROR */)) {
1317
+ this._throttleData = setBackoff(Number((_c = e.customData) === null || _c === void 0 ? void 0 : _c.httpStatus), this._throttleData);
1318
+ throw ERROR_FACTORY.create("throttled" /* AppCheckError.THROTTLED */, {
1319
+ time: getDurationString(this._throttleData.allowRequestsAfter - Date.now()),
1320
+ httpStatus: this._throttleData.httpStatus
1321
+ });
1322
+ }
1323
+ else {
1324
+ throw e;
1325
+ }
1326
+ }
1327
+ // If successful, clear throttle data.
1328
+ this._throttleData = null;
1329
+ return result;
1330
+ }
1484
1331
  /**
1485
1332
  * @internal
1486
1333
  */
1487
- ReCaptchaEnterpriseProvider.prototype.initialize = function (app$1) {
1334
+ initialize(app$1) {
1488
1335
  this._app = app$1;
1489
1336
  this._heartbeatServiceProvider = app._getProvider(app$1, 'heartbeat');
1490
- initializeEnterprise(app$1, this._siteKey).catch(function () {
1337
+ initializeEnterprise(app$1, this._siteKey).catch(() => {
1491
1338
  /* we don't care about the initialization result */
1492
1339
  });
1493
- };
1340
+ }
1494
1341
  /**
1495
1342
  * @internal
1496
1343
  */
1497
- ReCaptchaEnterpriseProvider.prototype.isEqual = function (otherProvider) {
1344
+ isEqual(otherProvider) {
1498
1345
  if (otherProvider instanceof ReCaptchaEnterpriseProvider) {
1499
1346
  return this._siteKey === otherProvider._siteKey;
1500
1347
  }
1501
1348
  else {
1502
1349
  return false;
1503
1350
  }
1504
- };
1505
- return ReCaptchaEnterpriseProvider;
1506
- }());
1351
+ }
1352
+ }
1507
1353
  /**
1508
1354
  * Custom provider class.
1509
1355
  * @public
1510
1356
  */
1511
- var CustomProvider = /** @class */ (function () {
1512
- function CustomProvider(_customProviderOptions) {
1357
+ class CustomProvider {
1358
+ constructor(_customProviderOptions) {
1513
1359
  this._customProviderOptions = _customProviderOptions;
1514
1360
  }
1515
1361
  /**
1516
1362
  * @internal
1517
1363
  */
1518
- CustomProvider.prototype.getToken = function () {
1519
- return tslib.__awaiter(this, void 0, void 0, function () {
1520
- var customToken, issuedAtTimeSeconds, issuedAtTimeMillis;
1521
- return tslib.__generator(this, function (_a) {
1522
- switch (_a.label) {
1523
- case 0: return [4 /*yield*/, this._customProviderOptions.getToken()];
1524
- case 1:
1525
- customToken = _a.sent();
1526
- issuedAtTimeSeconds = util.issuedAtTime(customToken.token);
1527
- issuedAtTimeMillis = issuedAtTimeSeconds !== null &&
1528
- issuedAtTimeSeconds < Date.now() &&
1529
- issuedAtTimeSeconds > 0
1530
- ? issuedAtTimeSeconds * 1000
1531
- : Date.now();
1532
- return [2 /*return*/, tslib.__assign(tslib.__assign({}, customToken), { issuedAtTimeMillis: issuedAtTimeMillis })];
1533
- }
1534
- });
1535
- });
1536
- };
1364
+ async getToken() {
1365
+ // custom provider
1366
+ const customToken = await this._customProviderOptions.getToken();
1367
+ // Try to extract IAT from custom token, in case this token is not
1368
+ // being newly issued. JWT timestamps are in seconds since epoch.
1369
+ const issuedAtTimeSeconds = util.issuedAtTime(customToken.token);
1370
+ // Very basic validation, use current timestamp as IAT if JWT
1371
+ // has no `iat` field or value is out of bounds.
1372
+ const issuedAtTimeMillis = issuedAtTimeSeconds !== null &&
1373
+ issuedAtTimeSeconds < Date.now() &&
1374
+ issuedAtTimeSeconds > 0
1375
+ ? issuedAtTimeSeconds * 1000
1376
+ : Date.now();
1377
+ return Object.assign(Object.assign({}, customToken), { issuedAtTimeMillis });
1378
+ }
1537
1379
  /**
1538
1380
  * @internal
1539
1381
  */
1540
- CustomProvider.prototype.initialize = function (app) {
1382
+ initialize(app) {
1541
1383
  this._app = app;
1542
- };
1384
+ }
1543
1385
  /**
1544
1386
  * @internal
1545
1387
  */
1546
- CustomProvider.prototype.isEqual = function (otherProvider) {
1388
+ isEqual(otherProvider) {
1547
1389
  if (otherProvider instanceof CustomProvider) {
1548
1390
  return (this._customProviderOptions.getToken.toString() ===
1549
1391
  otherProvider._customProviderOptions.getToken.toString());
@@ -1551,9 +1393,8 @@ var CustomProvider = /** @class */ (function () {
1551
1393
  else {
1552
1394
  return false;
1553
1395
  }
1554
- };
1555
- return CustomProvider;
1556
- }());
1396
+ }
1397
+ }
1557
1398
  /**
1558
1399
  * Set throttle data to block requests until after a certain time
1559
1400
  * depending on the failed request's status code.
@@ -1577,7 +1418,7 @@ function setBackoff(httpStatus, throttleData) {
1577
1418
  return {
1578
1419
  backoffCount: 1,
1579
1420
  allowRequestsAfter: Date.now() + ONE_DAY,
1580
- httpStatus: httpStatus
1421
+ httpStatus
1581
1422
  };
1582
1423
  }
1583
1424
  else {
@@ -1585,12 +1426,12 @@ function setBackoff(httpStatus, throttleData) {
1585
1426
  * For all other error codes, the time when it is ok to retry again
1586
1427
  * is based on exponential backoff.
1587
1428
  */
1588
- var backoffCount = throttleData ? throttleData.backoffCount : 0;
1589
- var backoffMillis = util.calculateBackoffMillis(backoffCount, 1000, 2);
1429
+ const backoffCount = throttleData ? throttleData.backoffCount : 0;
1430
+ const backoffMillis = util.calculateBackoffMillis(backoffCount, 1000, 2);
1590
1431
  return {
1591
1432
  backoffCount: backoffCount + 1,
1592
1433
  allowRequestsAfter: Date.now() + backoffMillis,
1593
- httpStatus: httpStatus
1434
+ httpStatus
1594
1435
  };
1595
1436
  }
1596
1437
  }
@@ -1628,10 +1469,9 @@ function throwIfThrottled(throttleData) {
1628
1469
  * @param options - App Check initialization options
1629
1470
  * @public
1630
1471
  */
1631
- function initializeAppCheck(app$1, options) {
1632
- if (app$1 === void 0) { app$1 = app.getApp(); }
1472
+ function initializeAppCheck(app$1 = app.getApp(), options) {
1633
1473
  app$1 = util.getModularInstance(app$1);
1634
- var provider = app._getProvider(app$1, 'app-check');
1474
+ const provider = app._getProvider(app$1, 'app-check');
1635
1475
  // Ensure initializeDebugMode() is only called once.
1636
1476
  if (!getDebugState().initialized) {
1637
1477
  initializeDebugMode();
@@ -1640,14 +1480,13 @@ function initializeAppCheck(app$1, options) {
1640
1480
  // is called in debug mode.
1641
1481
  if (isDebugMode()) {
1642
1482
  // Do not block initialization to get the token for the message.
1643
- void getDebugToken().then(function (token) {
1644
- // Not using logger because I don't think we ever want this accidentally hidden.
1645
- return console.log("App Check debug token: ".concat(token, ". You will need to add it to your app's App Check settings in the Firebase console for it to work."));
1646
- });
1483
+ void getDebugToken().then(token =>
1484
+ // Not using logger because I don't think we ever want this accidentally hidden.
1485
+ console.log(`App Check debug token: ${token}. You will need to add it to your app's App Check settings in the Firebase console for it to work.`));
1647
1486
  }
1648
1487
  if (provider.isInitialized()) {
1649
- var existingInstance = provider.getImmediate();
1650
- var initialOptions = provider.getOptions();
1488
+ const existingInstance = provider.getImmediate();
1489
+ const initialOptions = provider.getOptions();
1651
1490
  if (initialOptions.isTokenAutoRefreshEnabled ===
1652
1491
  options.isTokenAutoRefreshEnabled &&
1653
1492
  initialOptions.provider.isEqual(options.provider)) {
@@ -1659,7 +1498,7 @@ function initializeAppCheck(app$1, options) {
1659
1498
  });
1660
1499
  }
1661
1500
  }
1662
- var appCheck = provider.initialize({ options: options });
1501
+ const appCheck = provider.initialize({ options });
1663
1502
  _activate(app$1, options.provider, options.isTokenAutoRefreshEnabled);
1664
1503
  // If isTokenAutoRefreshEnabled is false, do not send any requests to the
1665
1504
  // exchange endpoint without an explicit call from the user either directly
@@ -1670,7 +1509,7 @@ function initializeAppCheck(app$1, options) {
1670
1509
  // requests the token.
1671
1510
  // Listener function does not need to do anything, its base functionality
1672
1511
  // of calling getToken() already fetches token and writes it to memory/storage.
1673
- addTokenListener(appCheck, "INTERNAL" /* ListenerType.INTERNAL */, function () { });
1512
+ addTokenListener(appCheck, "INTERNAL" /* ListenerType.INTERNAL */, () => { });
1674
1513
  }
1675
1514
  return appCheck;
1676
1515
  }
@@ -1687,10 +1526,10 @@ function initializeAppCheck(app$1, options) {
1687
1526
  function _activate(app, provider, isTokenAutoRefreshEnabled) {
1688
1527
  // Create an entry in the APP_CHECK_STATES map. Further changes should
1689
1528
  // directly mutate this object.
1690
- var state = setInitialState(app, tslib.__assign({}, DEFAULT_STATE));
1529
+ const state = setInitialState(app, Object.assign({}, DEFAULT_STATE));
1691
1530
  state.activated = true;
1692
1531
  state.provider = provider; // Read cached token from storage if it exists and store it in memory.
1693
- state.cachedTokenPromise = readTokenFromStorage(app).then(function (cachedToken) {
1532
+ state.cachedTokenPromise = readTokenFromStorage(app).then(cachedToken => {
1694
1533
  if (cachedToken && isValid(cachedToken)) {
1695
1534
  state.token = cachedToken;
1696
1535
  // notify all listeners with the cached token
@@ -1717,8 +1556,8 @@ function _activate(app, provider, isTokenAutoRefreshEnabled) {
1717
1556
  * @public
1718
1557
  */
1719
1558
  function setTokenAutoRefreshEnabled(appCheckInstance, isTokenAutoRefreshEnabled) {
1720
- var app = appCheckInstance.app;
1721
- var state = getStateReference(app);
1559
+ const app = appCheckInstance.app;
1560
+ const state = getStateReference(app);
1722
1561
  // This will exist if any product libraries have called
1723
1562
  // `addTokenListener()`
1724
1563
  if (state.tokenRefresher) {
@@ -1743,21 +1582,12 @@ function setTokenAutoRefreshEnabled(appCheckInstance, isTokenAutoRefreshEnabled)
1743
1582
  * If false, will use a cached token if found in storage.
1744
1583
  * @public
1745
1584
  */
1746
- function getToken(appCheckInstance, forceRefresh) {
1747
- return tslib.__awaiter(this, void 0, void 0, function () {
1748
- var result;
1749
- return tslib.__generator(this, function (_a) {
1750
- switch (_a.label) {
1751
- case 0: return [4 /*yield*/, getToken$2(appCheckInstance, forceRefresh)];
1752
- case 1:
1753
- result = _a.sent();
1754
- if (result.error) {
1755
- throw result.error;
1756
- }
1757
- return [2 /*return*/, { token: result.token }];
1758
- }
1759
- });
1760
- });
1585
+ async function getToken(appCheckInstance, forceRefresh) {
1586
+ const result = await getToken$2(appCheckInstance, forceRefresh);
1587
+ if (result.error) {
1588
+ throw result.error;
1589
+ }
1590
+ return { token: result.token };
1761
1591
  }
1762
1592
  /**
1763
1593
  * Requests a Firebase App Check token. This method should be used
@@ -1790,8 +1620,8 @@ function onTokenChanged(appCheckInstance, onNextOrObserver, onError,
1790
1620
  */
1791
1621
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
1792
1622
  onCompletion) {
1793
- var nextFn = function () { };
1794
- var errorFn = function () { };
1623
+ let nextFn = () => { };
1624
+ let errorFn = () => { };
1795
1625
  if (onNextOrObserver.next != null) {
1796
1626
  nextFn = onNextOrObserver.next.bind(onNextOrObserver);
1797
1627
  }
@@ -1805,7 +1635,7 @@ onCompletion) {
1805
1635
  errorFn = onError;
1806
1636
  }
1807
1637
  addTokenListener(appCheckInstance, "EXTERNAL" /* ListenerType.EXTERNAL */, nextFn, errorFn);
1808
- return function () { return removeTokenListener(appCheckInstance.app, nextFn); };
1638
+ return () => removeTokenListener(appCheckInstance.app, nextFn);
1809
1639
  }
1810
1640
 
1811
1641
  /**
@@ -1818,14 +1648,14 @@ onCompletion) {
1818
1648
  *
1819
1649
  * @packageDocumentation
1820
1650
  */
1821
- var APP_CHECK_NAME = 'app-check';
1822
- var APP_CHECK_NAME_INTERNAL = 'app-check-internal';
1651
+ const APP_CHECK_NAME = 'app-check';
1652
+ const APP_CHECK_NAME_INTERNAL = 'app-check-internal';
1823
1653
  function registerAppCheck() {
1824
1654
  // The public interface
1825
- app._registerComponent(new component.Component(APP_CHECK_NAME, function (container) {
1655
+ app._registerComponent(new component.Component(APP_CHECK_NAME, container => {
1826
1656
  // getImmediate for FirebaseApp will always succeed
1827
- var app = container.getProvider('app').getImmediate();
1828
- var heartbeatServiceProvider = container.getProvider('heartbeat');
1657
+ const app = container.getProvider('app').getImmediate();
1658
+ const heartbeatServiceProvider = container.getProvider('heartbeat');
1829
1659
  return factory(app, heartbeatServiceProvider);
1830
1660
  }, "PUBLIC" /* ComponentType.PUBLIC */)
1831
1661
  .setInstantiationMode("EXPLICIT" /* InstantiationMode.EXPLICIT */)
@@ -1833,12 +1663,12 @@ function registerAppCheck() {
1833
1663
  * Initialize app-check-internal after app-check is initialized to make AppCheck available to
1834
1664
  * other Firebase SDKs
1835
1665
  */
1836
- .setInstanceCreatedCallback(function (container, _identifier, _appcheckService) {
1666
+ .setInstanceCreatedCallback((container, _identifier, _appcheckService) => {
1837
1667
  container.getProvider(APP_CHECK_NAME_INTERNAL).initialize();
1838
1668
  }));
1839
1669
  // The internal interface used by other Firebase products
1840
- app._registerComponent(new component.Component(APP_CHECK_NAME_INTERNAL, function (container) {
1841
- var appCheck = container.getProvider('app-check').getImmediate();
1670
+ app._registerComponent(new component.Component(APP_CHECK_NAME_INTERNAL, container => {
1671
+ const appCheck = container.getProvider('app-check').getImmediate();
1842
1672
  return internalFactory(appCheck);
1843
1673
  }, "PUBLIC" /* ComponentType.PUBLIC */).setInstantiationMode("EXPLICIT" /* InstantiationMode.EXPLICIT */));
1844
1674
  app.registerVersion(name, version);