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