@thefittingroom/shop-ui 1.5.1 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/index.js +983 -491
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.min.js +222 -192
- package/package.json +2 -2
package/dist/esm/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* thefittingroom v1.5.
|
|
2
|
+
* thefittingroom v1.5.2 (2024-09-02T22:33:59.821Z)
|
|
3
3
|
* Copyright 2022-present, TheFittingRoom, Inc. All rights reserved.
|
|
4
4
|
*/
|
|
5
5
|
function loadImageRecursive(imageURL, imageURLs) {
|
|
@@ -47,7 +47,7 @@ const InitImageSlider = (sliderID, onChange) => {
|
|
|
47
47
|
};
|
|
48
48
|
|
|
49
49
|
/*!
|
|
50
|
-
* thefittingroom v1.5.
|
|
50
|
+
* thefittingroom v1.5.1 (2024-09-02T22:33:26.212Z)
|
|
51
51
|
* Copyright 2022-present, TheFittingRoom, Inc. All rights reserved.
|
|
52
52
|
*/
|
|
53
53
|
|
|
@@ -1986,8 +1986,8 @@ function isVersionServiceProvider(provider) {
|
|
|
1986
1986
|
return (component === null || component === void 0 ? void 0 : component.type) === "VERSION" /* ComponentType.VERSION */;
|
|
1987
1987
|
}
|
|
1988
1988
|
|
|
1989
|
-
const name$
|
|
1990
|
-
const version$1$1 = "0.9
|
|
1989
|
+
const name$p = "@firebase/app";
|
|
1990
|
+
const version$1$1 = "0.10.9";
|
|
1991
1991
|
|
|
1992
1992
|
/**
|
|
1993
1993
|
* @license
|
|
@@ -2007,54 +2007,56 @@ const version$1$1 = "0.9.13";
|
|
|
2007
2007
|
*/
|
|
2008
2008
|
const logger = new Logger$1('@firebase/app');
|
|
2009
2009
|
|
|
2010
|
-
const name$
|
|
2010
|
+
const name$o = "@firebase/app-compat";
|
|
2011
2011
|
|
|
2012
|
-
const name$
|
|
2012
|
+
const name$n = "@firebase/analytics-compat";
|
|
2013
2013
|
|
|
2014
|
-
const name$
|
|
2014
|
+
const name$m = "@firebase/analytics";
|
|
2015
2015
|
|
|
2016
|
-
const name$
|
|
2016
|
+
const name$l = "@firebase/app-check-compat";
|
|
2017
2017
|
|
|
2018
|
-
const name$
|
|
2018
|
+
const name$k = "@firebase/app-check";
|
|
2019
2019
|
|
|
2020
|
-
const name$
|
|
2020
|
+
const name$j = "@firebase/auth";
|
|
2021
2021
|
|
|
2022
|
-
const name$
|
|
2022
|
+
const name$i = "@firebase/auth-compat";
|
|
2023
2023
|
|
|
2024
|
-
const name$
|
|
2024
|
+
const name$h = "@firebase/database";
|
|
2025
2025
|
|
|
2026
|
-
const name$
|
|
2026
|
+
const name$g = "@firebase/database-compat";
|
|
2027
2027
|
|
|
2028
|
-
const name$
|
|
2028
|
+
const name$f = "@firebase/functions";
|
|
2029
2029
|
|
|
2030
|
-
const name$
|
|
2030
|
+
const name$e = "@firebase/functions-compat";
|
|
2031
2031
|
|
|
2032
|
-
const name$
|
|
2032
|
+
const name$d = "@firebase/installations";
|
|
2033
2033
|
|
|
2034
|
-
const name$
|
|
2034
|
+
const name$c = "@firebase/installations-compat";
|
|
2035
2035
|
|
|
2036
|
-
const name$
|
|
2036
|
+
const name$b = "@firebase/messaging";
|
|
2037
2037
|
|
|
2038
|
-
const name$
|
|
2038
|
+
const name$a = "@firebase/messaging-compat";
|
|
2039
2039
|
|
|
2040
|
-
const name$
|
|
2040
|
+
const name$9 = "@firebase/performance";
|
|
2041
2041
|
|
|
2042
|
-
const name$
|
|
2042
|
+
const name$8 = "@firebase/performance-compat";
|
|
2043
2043
|
|
|
2044
|
-
const name$
|
|
2044
|
+
const name$7 = "@firebase/remote-config";
|
|
2045
2045
|
|
|
2046
|
-
const name$
|
|
2046
|
+
const name$6 = "@firebase/remote-config-compat";
|
|
2047
2047
|
|
|
2048
|
-
const name$
|
|
2048
|
+
const name$5 = "@firebase/storage";
|
|
2049
2049
|
|
|
2050
|
-
const name$
|
|
2050
|
+
const name$4 = "@firebase/storage-compat";
|
|
2051
2051
|
|
|
2052
|
-
const name$
|
|
2052
|
+
const name$3 = "@firebase/firestore";
|
|
2053
|
+
|
|
2054
|
+
const name$2 = "@firebase/vertexai-preview";
|
|
2053
2055
|
|
|
2054
2056
|
const name$1$1 = "@firebase/firestore-compat";
|
|
2055
2057
|
|
|
2056
|
-
const name$
|
|
2057
|
-
const version$2 = "
|
|
2058
|
+
const name$q = "firebase";
|
|
2059
|
+
const version$2 = "10.13.0";
|
|
2058
2060
|
|
|
2059
2061
|
/**
|
|
2060
2062
|
* @license
|
|
@@ -2079,32 +2081,33 @@ const version$2 = "9.23.0";
|
|
|
2079
2081
|
*/
|
|
2080
2082
|
const DEFAULT_ENTRY_NAME = '[DEFAULT]';
|
|
2081
2083
|
const PLATFORM_LOG_STRING = {
|
|
2082
|
-
[name$
|
|
2083
|
-
[name$
|
|
2084
|
-
[name$
|
|
2085
|
-
[name$
|
|
2086
|
-
[name$
|
|
2087
|
-
[name$
|
|
2088
|
-
[name$
|
|
2089
|
-
[name$
|
|
2090
|
-
[name$
|
|
2091
|
-
[name$
|
|
2092
|
-
[name$
|
|
2093
|
-
[name$
|
|
2094
|
-
[name$
|
|
2095
|
-
[name$
|
|
2096
|
-
[name$
|
|
2097
|
-
[name$
|
|
2098
|
-
[name$
|
|
2099
|
-
[name$
|
|
2100
|
-
[name$
|
|
2101
|
-
[name$
|
|
2102
|
-
[name$
|
|
2103
|
-
[name$
|
|
2104
|
-
[name$
|
|
2084
|
+
[name$p]: 'fire-core',
|
|
2085
|
+
[name$o]: 'fire-core-compat',
|
|
2086
|
+
[name$m]: 'fire-analytics',
|
|
2087
|
+
[name$n]: 'fire-analytics-compat',
|
|
2088
|
+
[name$k]: 'fire-app-check',
|
|
2089
|
+
[name$l]: 'fire-app-check-compat',
|
|
2090
|
+
[name$j]: 'fire-auth',
|
|
2091
|
+
[name$i]: 'fire-auth-compat',
|
|
2092
|
+
[name$h]: 'fire-rtdb',
|
|
2093
|
+
[name$g]: 'fire-rtdb-compat',
|
|
2094
|
+
[name$f]: 'fire-fn',
|
|
2095
|
+
[name$e]: 'fire-fn-compat',
|
|
2096
|
+
[name$d]: 'fire-iid',
|
|
2097
|
+
[name$c]: 'fire-iid-compat',
|
|
2098
|
+
[name$b]: 'fire-fcm',
|
|
2099
|
+
[name$a]: 'fire-fcm-compat',
|
|
2100
|
+
[name$9]: 'fire-perf',
|
|
2101
|
+
[name$8]: 'fire-perf-compat',
|
|
2102
|
+
[name$7]: 'fire-rc',
|
|
2103
|
+
[name$6]: 'fire-rc-compat',
|
|
2104
|
+
[name$5]: 'fire-gcs',
|
|
2105
|
+
[name$4]: 'fire-gcs-compat',
|
|
2106
|
+
[name$3]: 'fire-fst',
|
|
2105
2107
|
[name$1$1]: 'fire-fst-compat',
|
|
2108
|
+
[name$2]: 'fire-vertex',
|
|
2106
2109
|
'fire-js': 'fire-js',
|
|
2107
|
-
[name$
|
|
2110
|
+
[name$q]: 'fire-js-all'
|
|
2108
2111
|
};
|
|
2109
2112
|
|
|
2110
2113
|
/**
|
|
@@ -2127,6 +2130,10 @@ const PLATFORM_LOG_STRING = {
|
|
|
2127
2130
|
* @internal
|
|
2128
2131
|
*/
|
|
2129
2132
|
const _apps = new Map();
|
|
2133
|
+
/**
|
|
2134
|
+
* @internal
|
|
2135
|
+
*/
|
|
2136
|
+
const _serverApps = new Map();
|
|
2130
2137
|
/**
|
|
2131
2138
|
* Registered components.
|
|
2132
2139
|
*
|
|
@@ -2165,6 +2172,9 @@ function _registerComponent(component) {
|
|
|
2165
2172
|
for (const app of _apps.values()) {
|
|
2166
2173
|
_addComponent(app, component);
|
|
2167
2174
|
}
|
|
2175
|
+
for (const serverApp of _serverApps.values()) {
|
|
2176
|
+
_addComponent(serverApp, component);
|
|
2177
|
+
}
|
|
2168
2178
|
return true;
|
|
2169
2179
|
}
|
|
2170
2180
|
/**
|
|
@@ -2185,6 +2195,17 @@ function _getProvider(app, name) {
|
|
|
2185
2195
|
}
|
|
2186
2196
|
return app.container.getProvider(name);
|
|
2187
2197
|
}
|
|
2198
|
+
/**
|
|
2199
|
+
*
|
|
2200
|
+
* @param obj - an object of type FirebaseApp.
|
|
2201
|
+
*
|
|
2202
|
+
* @returns true if the provided object is of type FirebaseServerAppImpl.
|
|
2203
|
+
*
|
|
2204
|
+
* @internal
|
|
2205
|
+
*/
|
|
2206
|
+
function _isFirebaseServerApp(obj) {
|
|
2207
|
+
return obj.settings !== undefined;
|
|
2208
|
+
}
|
|
2188
2209
|
|
|
2189
2210
|
/**
|
|
2190
2211
|
* @license
|
|
@@ -2205,9 +2226,10 @@ function _getProvider(app, name) {
|
|
|
2205
2226
|
const ERRORS = {
|
|
2206
2227
|
["no-app" /* AppError.NO_APP */]: "No Firebase App '{$appName}' has been created - " +
|
|
2207
2228
|
'call initializeApp() first',
|
|
2208
|
-
["bad-app-name" /* AppError.BAD_APP_NAME */]: "Illegal App name: '{$appName}",
|
|
2229
|
+
["bad-app-name" /* AppError.BAD_APP_NAME */]: "Illegal App name: '{$appName}'",
|
|
2209
2230
|
["duplicate-app" /* AppError.DUPLICATE_APP */]: "Firebase App named '{$appName}' already exists with different options or config",
|
|
2210
2231
|
["app-deleted" /* AppError.APP_DELETED */]: "Firebase App named '{$appName}' already deleted",
|
|
2232
|
+
["server-app-deleted" /* AppError.SERVER_APP_DELETED */]: 'Firebase Server App has been deleted',
|
|
2211
2233
|
["no-options" /* AppError.NO_OPTIONS */]: 'Need to provide options, when not being deployed to hosting via source.',
|
|
2212
2234
|
["invalid-app-argument" /* AppError.INVALID_APP_ARGUMENT */]: 'firebase.{$appName}() takes either no argument or a ' +
|
|
2213
2235
|
'Firebase App instance.',
|
|
@@ -2215,7 +2237,9 @@ const ERRORS = {
|
|
|
2215
2237
|
["idb-open" /* AppError.IDB_OPEN */]: 'Error thrown when opening IndexedDB. Original error: {$originalErrorMessage}.',
|
|
2216
2238
|
["idb-get" /* AppError.IDB_GET */]: 'Error thrown when reading from IndexedDB. Original error: {$originalErrorMessage}.',
|
|
2217
2239
|
["idb-set" /* AppError.IDB_WRITE */]: 'Error thrown when writing to IndexedDB. Original error: {$originalErrorMessage}.',
|
|
2218
|
-
["idb-delete" /* AppError.IDB_DELETE */]: 'Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}.'
|
|
2240
|
+
["idb-delete" /* AppError.IDB_DELETE */]: 'Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}.',
|
|
2241
|
+
["finalization-registry-not-supported" /* AppError.FINALIZATION_REGISTRY_NOT_SUPPORTED */]: 'FirebaseServerApp deleteOnDeref field defined but the JS runtime does not support FinalizationRegistry.',
|
|
2242
|
+
["invalid-server-app-environment" /* AppError.INVALID_SERVER_APP_ENVIRONMENT */]: 'FirebaseServerApp is not for use in browser environments.'
|
|
2219
2243
|
};
|
|
2220
2244
|
const ERROR_FACTORY = new ErrorFactory$1('app', 'Firebase', ERRORS);
|
|
2221
2245
|
|
|
@@ -2451,7 +2475,15 @@ function getDbPromise() {
|
|
|
2451
2475
|
// eslint-disable-next-line default-case
|
|
2452
2476
|
switch (oldVersion) {
|
|
2453
2477
|
case 0:
|
|
2454
|
-
|
|
2478
|
+
try {
|
|
2479
|
+
db.createObjectStore(STORE_NAME);
|
|
2480
|
+
}
|
|
2481
|
+
catch (e) {
|
|
2482
|
+
// Safari/iOS browsers throw occasional exceptions on
|
|
2483
|
+
// db.createObjectStore() that may be a bug. Avoid blocking
|
|
2484
|
+
// the rest of the app functionality.
|
|
2485
|
+
console.warn(e);
|
|
2486
|
+
}
|
|
2455
2487
|
}
|
|
2456
2488
|
}
|
|
2457
2489
|
}).catch(e => {
|
|
@@ -2465,10 +2497,11 @@ function getDbPromise() {
|
|
|
2465
2497
|
async function readHeartbeatsFromIndexedDB(app) {
|
|
2466
2498
|
try {
|
|
2467
2499
|
const db = await getDbPromise();
|
|
2468
|
-
const
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2500
|
+
const tx = db.transaction(STORE_NAME);
|
|
2501
|
+
const result = await tx.objectStore(STORE_NAME).get(computeKey(app));
|
|
2502
|
+
// We already have the value but tx.done can throw,
|
|
2503
|
+
// so we need to await it here to catch errors
|
|
2504
|
+
await tx.done;
|
|
2472
2505
|
return result;
|
|
2473
2506
|
}
|
|
2474
2507
|
catch (e) {
|
|
@@ -2554,33 +2587,45 @@ class HeartbeatServiceImpl {
|
|
|
2554
2587
|
* already logged, subsequent calls to this function in the same day will be ignored.
|
|
2555
2588
|
*/
|
|
2556
2589
|
async triggerHeartbeat() {
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
.
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2590
|
+
var _a, _b, _c;
|
|
2591
|
+
try {
|
|
2592
|
+
const platformLogger = this.container
|
|
2593
|
+
.getProvider('platform-logger')
|
|
2594
|
+
.getImmediate();
|
|
2595
|
+
// This is the "Firebase user agent" string from the platform logger
|
|
2596
|
+
// service, not the browser user agent.
|
|
2597
|
+
const agent = platformLogger.getPlatformInfoString();
|
|
2598
|
+
const date = getUTCDateString();
|
|
2599
|
+
console.log('heartbeats', (_a = this._heartbeatsCache) === null || _a === void 0 ? void 0 : _a.heartbeats);
|
|
2600
|
+
if (((_b = this._heartbeatsCache) === null || _b === void 0 ? void 0 : _b.heartbeats) == null) {
|
|
2601
|
+
this._heartbeatsCache = await this._heartbeatsCachePromise;
|
|
2602
|
+
// If we failed to construct a heartbeats cache, then return immediately.
|
|
2603
|
+
if (((_c = this._heartbeatsCache) === null || _c === void 0 ? void 0 : _c.heartbeats) == null) {
|
|
2604
|
+
return;
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
// Do not store a heartbeat if one is already stored for this day
|
|
2608
|
+
// or if a header has already been sent today.
|
|
2609
|
+
if (this._heartbeatsCache.lastSentHeartbeatDate === date ||
|
|
2610
|
+
this._heartbeatsCache.heartbeats.some(singleDateHeartbeat => singleDateHeartbeat.date === date)) {
|
|
2611
|
+
return;
|
|
2612
|
+
}
|
|
2613
|
+
else {
|
|
2614
|
+
// There is no entry for this date. Create one.
|
|
2615
|
+
this._heartbeatsCache.heartbeats.push({ date, agent });
|
|
2616
|
+
}
|
|
2617
|
+
// Remove entries older than 30 days.
|
|
2618
|
+
this._heartbeatsCache.heartbeats =
|
|
2619
|
+
this._heartbeatsCache.heartbeats.filter(singleDateHeartbeat => {
|
|
2620
|
+
const hbTimestamp = new Date(singleDateHeartbeat.date).valueOf();
|
|
2621
|
+
const now = Date.now();
|
|
2622
|
+
return now - hbTimestamp <= STORED_HEARTBEAT_RETENTION_MAX_MILLIS;
|
|
2623
|
+
});
|
|
2624
|
+
return this._storage.overwrite(this._heartbeatsCache);
|
|
2625
|
+
}
|
|
2626
|
+
catch (e) {
|
|
2627
|
+
logger.warn(e);
|
|
2572
2628
|
}
|
|
2573
|
-
else {
|
|
2574
|
-
// There is no entry for this date. Create one.
|
|
2575
|
-
this._heartbeatsCache.heartbeats.push({ date, agent });
|
|
2576
|
-
}
|
|
2577
|
-
// Remove entries older than 30 days.
|
|
2578
|
-
this._heartbeatsCache.heartbeats = this._heartbeatsCache.heartbeats.filter(singleDateHeartbeat => {
|
|
2579
|
-
const hbTimestamp = new Date(singleDateHeartbeat.date).valueOf();
|
|
2580
|
-
const now = Date.now();
|
|
2581
|
-
return now - hbTimestamp <= STORED_HEARTBEAT_RETENTION_MAX_MILLIS;
|
|
2582
|
-
});
|
|
2583
|
-
return this._storage.overwrite(this._heartbeatsCache);
|
|
2584
2629
|
}
|
|
2585
2630
|
/**
|
|
2586
2631
|
* Returns a base64 encoded string which can be attached to the heartbeat-specific header directly.
|
|
@@ -2590,34 +2635,41 @@ class HeartbeatServiceImpl {
|
|
|
2590
2635
|
* returns an empty string.
|
|
2591
2636
|
*/
|
|
2592
2637
|
async getHeartbeatsHeader() {
|
|
2593
|
-
|
|
2594
|
-
|
|
2638
|
+
var _a;
|
|
2639
|
+
try {
|
|
2640
|
+
if (this._heartbeatsCache === null) {
|
|
2641
|
+
await this._heartbeatsCachePromise;
|
|
2642
|
+
}
|
|
2643
|
+
// If it's still null or the array is empty, there is no data to send.
|
|
2644
|
+
if (((_a = this._heartbeatsCache) === null || _a === void 0 ? void 0 : _a.heartbeats) == null ||
|
|
2645
|
+
this._heartbeatsCache.heartbeats.length === 0) {
|
|
2646
|
+
return '';
|
|
2647
|
+
}
|
|
2648
|
+
const date = getUTCDateString();
|
|
2649
|
+
// Extract as many heartbeats from the cache as will fit under the size limit.
|
|
2650
|
+
const { heartbeatsToSend, unsentEntries } = extractHeartbeatsForHeader(this._heartbeatsCache.heartbeats);
|
|
2651
|
+
const headerString = base64urlEncodeWithoutPadding$1(JSON.stringify({ version: 2, heartbeats: heartbeatsToSend }));
|
|
2652
|
+
// Store last sent date to prevent another being logged/sent for the same day.
|
|
2653
|
+
this._heartbeatsCache.lastSentHeartbeatDate = date;
|
|
2654
|
+
if (unsentEntries.length > 0) {
|
|
2655
|
+
// Store any unsent entries if they exist.
|
|
2656
|
+
this._heartbeatsCache.heartbeats = unsentEntries;
|
|
2657
|
+
// This seems more likely than emptying the array (below) to lead to some odd state
|
|
2658
|
+
// since the cache isn't empty and this will be called again on the next request,
|
|
2659
|
+
// and is probably safest if we await it.
|
|
2660
|
+
await this._storage.overwrite(this._heartbeatsCache);
|
|
2661
|
+
}
|
|
2662
|
+
else {
|
|
2663
|
+
this._heartbeatsCache.heartbeats = [];
|
|
2664
|
+
// Do not wait for this, to reduce latency.
|
|
2665
|
+
void this._storage.overwrite(this._heartbeatsCache);
|
|
2666
|
+
}
|
|
2667
|
+
return headerString;
|
|
2595
2668
|
}
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
this._heartbeatsCache.heartbeats.length === 0) {
|
|
2669
|
+
catch (e) {
|
|
2670
|
+
logger.warn(e);
|
|
2599
2671
|
return '';
|
|
2600
2672
|
}
|
|
2601
|
-
const date = getUTCDateString();
|
|
2602
|
-
// Extract as many heartbeats from the cache as will fit under the size limit.
|
|
2603
|
-
const { heartbeatsToSend, unsentEntries } = extractHeartbeatsForHeader(this._heartbeatsCache.heartbeats);
|
|
2604
|
-
const headerString = base64urlEncodeWithoutPadding$1(JSON.stringify({ version: 2, heartbeats: heartbeatsToSend }));
|
|
2605
|
-
// Store last sent date to prevent another being logged/sent for the same day.
|
|
2606
|
-
this._heartbeatsCache.lastSentHeartbeatDate = date;
|
|
2607
|
-
if (unsentEntries.length > 0) {
|
|
2608
|
-
// Store any unsent entries if they exist.
|
|
2609
|
-
this._heartbeatsCache.heartbeats = unsentEntries;
|
|
2610
|
-
// This seems more likely than emptying the array (below) to lead to some odd state
|
|
2611
|
-
// since the cache isn't empty and this will be called again on the next request,
|
|
2612
|
-
// and is probably safest if we await it.
|
|
2613
|
-
await this._storage.overwrite(this._heartbeatsCache);
|
|
2614
|
-
}
|
|
2615
|
-
else {
|
|
2616
|
-
this._heartbeatsCache.heartbeats = [];
|
|
2617
|
-
// Do not wait for this, to reduce latency.
|
|
2618
|
-
void this._storage.overwrite(this._heartbeatsCache);
|
|
2619
|
-
}
|
|
2620
|
-
return headerString;
|
|
2621
2673
|
}
|
|
2622
2674
|
}
|
|
2623
2675
|
function getUTCDateString() {
|
|
@@ -2690,7 +2742,12 @@ class HeartbeatStorageImpl {
|
|
|
2690
2742
|
}
|
|
2691
2743
|
else {
|
|
2692
2744
|
const idbHeartbeatObject = await readHeartbeatsFromIndexedDB(this.app);
|
|
2693
|
-
|
|
2745
|
+
if (idbHeartbeatObject === null || idbHeartbeatObject === void 0 ? void 0 : idbHeartbeatObject.heartbeats) {
|
|
2746
|
+
return idbHeartbeatObject;
|
|
2747
|
+
}
|
|
2748
|
+
else {
|
|
2749
|
+
return { heartbeats: [] };
|
|
2750
|
+
}
|
|
2694
2751
|
}
|
|
2695
2752
|
}
|
|
2696
2753
|
// overwrite the storage with the provided heartbeats
|
|
@@ -2759,9 +2816,9 @@ function registerCoreComponents(variant) {
|
|
|
2759
2816
|
_registerComponent(new Component$1('platform-logger', container => new PlatformLoggerServiceImpl(container), "PRIVATE" /* ComponentType.PRIVATE */));
|
|
2760
2817
|
_registerComponent(new Component$1('heartbeat', container => new HeartbeatServiceImpl(container), "PRIVATE" /* ComponentType.PRIVATE */));
|
|
2761
2818
|
// Register `app` package.
|
|
2762
|
-
registerVersion(name$
|
|
2819
|
+
registerVersion(name$p, version$1$1, variant);
|
|
2763
2820
|
// BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
|
|
2764
|
-
registerVersion(name$
|
|
2821
|
+
registerVersion(name$p, version$1$1, 'esm2017');
|
|
2765
2822
|
// Register platform SDK identifier (no version).
|
|
2766
2823
|
registerVersion('fire-js', '');
|
|
2767
2824
|
}
|
|
@@ -17828,7 +17885,7 @@ function jl(t, ...e) {
|
|
|
17828
17885
|
}();
|
|
17829
17886
|
|
|
17830
17887
|
var name$1 = "firebase";
|
|
17831
|
-
var version$1 = "
|
|
17888
|
+
var version$1 = "10.13.0";
|
|
17832
17889
|
|
|
17833
17890
|
/**
|
|
17834
17891
|
* @license
|
|
@@ -18644,6 +18701,7 @@ const AUTH_ERROR_CODES_MAP_DO_NOT_USE_INTERNALLY = {
|
|
|
18644
18701
|
INVALID_EMAIL: 'auth/invalid-email',
|
|
18645
18702
|
INVALID_EMULATOR_SCHEME: 'auth/invalid-emulator-scheme',
|
|
18646
18703
|
INVALID_IDP_RESPONSE: 'auth/invalid-credential',
|
|
18704
|
+
INVALID_LOGIN_CREDENTIALS: 'auth/invalid-credential',
|
|
18647
18705
|
INVALID_MESSAGE_PAYLOAD: 'auth/invalid-message-payload',
|
|
18648
18706
|
INVALID_MFA_SESSION: 'auth/invalid-multi-factor-session',
|
|
18649
18707
|
INVALID_OAUTH_CLIENT_ID: 'auth/invalid-oauth-client-id',
|
|
@@ -18773,6 +18831,9 @@ function _errorWithCustomMessage(auth, code, message) {
|
|
|
18773
18831
|
appName: auth.name
|
|
18774
18832
|
});
|
|
18775
18833
|
}
|
|
18834
|
+
function _serverAppCurrentUserOperationNotSupportedError(auth) {
|
|
18835
|
+
return _errorWithCustomMessage(auth, "operation-not-supported-in-this-environment" /* AuthErrorCode.OPERATION_NOT_SUPPORTED */, 'Operations that alter the current user are not supported in conjunction with FirebaseServerApp');
|
|
18836
|
+
}
|
|
18776
18837
|
function createErrorInternal(authOrCode, ...rest) {
|
|
18777
18838
|
if (typeof authOrCode !== 'string') {
|
|
18778
18839
|
const code = rest[0];
|
|
@@ -18996,6 +19057,12 @@ class FetchProvider {
|
|
|
18996
19057
|
if (typeof self !== 'undefined' && 'fetch' in self) {
|
|
18997
19058
|
return self.fetch;
|
|
18998
19059
|
}
|
|
19060
|
+
if (typeof globalThis !== 'undefined' && globalThis.fetch) {
|
|
19061
|
+
return globalThis.fetch;
|
|
19062
|
+
}
|
|
19063
|
+
if (typeof fetch !== 'undefined') {
|
|
19064
|
+
return fetch;
|
|
19065
|
+
}
|
|
18999
19066
|
debugFail('Could not find fetch implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill');
|
|
19000
19067
|
}
|
|
19001
19068
|
static headers() {
|
|
@@ -19005,6 +19072,12 @@ class FetchProvider {
|
|
|
19005
19072
|
if (typeof self !== 'undefined' && 'Headers' in self) {
|
|
19006
19073
|
return self.Headers;
|
|
19007
19074
|
}
|
|
19075
|
+
if (typeof globalThis !== 'undefined' && globalThis.Headers) {
|
|
19076
|
+
return globalThis.Headers;
|
|
19077
|
+
}
|
|
19078
|
+
if (typeof Headers !== 'undefined') {
|
|
19079
|
+
return Headers;
|
|
19080
|
+
}
|
|
19008
19081
|
debugFail('Could not find Headers implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill');
|
|
19009
19082
|
}
|
|
19010
19083
|
static response() {
|
|
@@ -19014,6 +19087,12 @@ class FetchProvider {
|
|
|
19014
19087
|
if (typeof self !== 'undefined' && 'Response' in self) {
|
|
19015
19088
|
return self.Response;
|
|
19016
19089
|
}
|
|
19090
|
+
if (typeof globalThis !== 'undefined' && globalThis.Response) {
|
|
19091
|
+
return globalThis.Response;
|
|
19092
|
+
}
|
|
19093
|
+
if (typeof Response !== 'undefined') {
|
|
19094
|
+
return Response;
|
|
19095
|
+
}
|
|
19017
19096
|
debugFail('Could not find Response implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill');
|
|
19018
19097
|
}
|
|
19019
19098
|
}
|
|
@@ -19050,12 +19129,15 @@ const SERVER_ERROR_MAP = {
|
|
|
19050
19129
|
["INVALID_PASSWORD" /* ServerError.INVALID_PASSWORD */]: "wrong-password" /* AuthErrorCode.INVALID_PASSWORD */,
|
|
19051
19130
|
// This can only happen if the SDK sends a bad request.
|
|
19052
19131
|
["MISSING_PASSWORD" /* ServerError.MISSING_PASSWORD */]: "missing-password" /* AuthErrorCode.MISSING_PASSWORD */,
|
|
19132
|
+
// Thrown if Email Enumeration Protection is enabled in the project and the email or password is
|
|
19133
|
+
// invalid.
|
|
19134
|
+
["INVALID_LOGIN_CREDENTIALS" /* ServerError.INVALID_LOGIN_CREDENTIALS */]: "invalid-credential" /* AuthErrorCode.INVALID_CREDENTIAL */,
|
|
19053
19135
|
// Sign up with email and password errors.
|
|
19054
19136
|
["EMAIL_EXISTS" /* ServerError.EMAIL_EXISTS */]: "email-already-in-use" /* AuthErrorCode.EMAIL_EXISTS */,
|
|
19055
19137
|
["PASSWORD_LOGIN_DISABLED" /* ServerError.PASSWORD_LOGIN_DISABLED */]: "operation-not-allowed" /* AuthErrorCode.OPERATION_NOT_ALLOWED */,
|
|
19056
19138
|
// Verify assertion for sign in with credential errors:
|
|
19057
|
-
["INVALID_IDP_RESPONSE" /* ServerError.INVALID_IDP_RESPONSE */]: "invalid-credential" /* AuthErrorCode.
|
|
19058
|
-
["INVALID_PENDING_TOKEN" /* ServerError.INVALID_PENDING_TOKEN */]: "invalid-credential" /* AuthErrorCode.
|
|
19139
|
+
["INVALID_IDP_RESPONSE" /* ServerError.INVALID_IDP_RESPONSE */]: "invalid-credential" /* AuthErrorCode.INVALID_CREDENTIAL */,
|
|
19140
|
+
["INVALID_PENDING_TOKEN" /* ServerError.INVALID_PENDING_TOKEN */]: "invalid-credential" /* AuthErrorCode.INVALID_CREDENTIAL */,
|
|
19059
19141
|
["FEDERATED_USER_ID_ALREADY_LINKED" /* ServerError.FEDERATED_USER_ID_ALREADY_LINKED */]: "credential-already-in-use" /* AuthErrorCode.CREDENTIAL_ALREADY_IN_USE */,
|
|
19060
19142
|
// This can only happen if the SDK sends a bad request.
|
|
19061
19143
|
["MISSING_REQ_TYPE" /* ServerError.MISSING_REQ_TYPE */]: "internal-error" /* AuthErrorCode.INTERNAL_ERROR */,
|
|
@@ -19073,10 +19155,11 @@ const SERVER_ERROR_MAP = {
|
|
|
19073
19155
|
["USER_NOT_FOUND" /* ServerError.USER_NOT_FOUND */]: "user-token-expired" /* AuthErrorCode.TOKEN_EXPIRED */,
|
|
19074
19156
|
// Other errors.
|
|
19075
19157
|
["TOO_MANY_ATTEMPTS_TRY_LATER" /* ServerError.TOO_MANY_ATTEMPTS_TRY_LATER */]: "too-many-requests" /* AuthErrorCode.TOO_MANY_ATTEMPTS_TRY_LATER */,
|
|
19158
|
+
["PASSWORD_DOES_NOT_MEET_REQUIREMENTS" /* ServerError.PASSWORD_DOES_NOT_MEET_REQUIREMENTS */]: "password-does-not-meet-requirements" /* AuthErrorCode.PASSWORD_DOES_NOT_MEET_REQUIREMENTS */,
|
|
19076
19159
|
// Phone Auth related errors.
|
|
19077
19160
|
["INVALID_CODE" /* ServerError.INVALID_CODE */]: "invalid-verification-code" /* AuthErrorCode.INVALID_CODE */,
|
|
19078
19161
|
["INVALID_SESSION_INFO" /* ServerError.INVALID_SESSION_INFO */]: "invalid-verification-id" /* AuthErrorCode.INVALID_SESSION_INFO */,
|
|
19079
|
-
["INVALID_TEMPORARY_PROOF" /* ServerError.INVALID_TEMPORARY_PROOF */]: "invalid-credential" /* AuthErrorCode.
|
|
19162
|
+
["INVALID_TEMPORARY_PROOF" /* ServerError.INVALID_TEMPORARY_PROOF */]: "invalid-credential" /* AuthErrorCode.INVALID_CREDENTIAL */,
|
|
19080
19163
|
["MISSING_SESSION_INFO" /* ServerError.MISSING_SESSION_INFO */]: "missing-verification-id" /* AuthErrorCode.MISSING_SESSION_INFO */,
|
|
19081
19164
|
["SESSION_EXPIRED" /* ServerError.SESSION_EXPIRED */]: "code-expired" /* AuthErrorCode.CODE_EXPIRED */,
|
|
19082
19165
|
// Other action code errors when additional settings passed.
|
|
@@ -19224,6 +19307,18 @@ function _getFinalTarget(auth, host, path, query) {
|
|
|
19224
19307
|
}
|
|
19225
19308
|
return _emulatorUrl(auth.config, base);
|
|
19226
19309
|
}
|
|
19310
|
+
function _parseEnforcementState(enforcementStateStr) {
|
|
19311
|
+
switch (enforcementStateStr) {
|
|
19312
|
+
case 'ENFORCE':
|
|
19313
|
+
return "ENFORCE" /* EnforcementState.ENFORCE */;
|
|
19314
|
+
case 'AUDIT':
|
|
19315
|
+
return "AUDIT" /* EnforcementState.AUDIT */;
|
|
19316
|
+
case 'OFF':
|
|
19317
|
+
return "OFF" /* EnforcementState.OFF */;
|
|
19318
|
+
default:
|
|
19319
|
+
return "ENFORCEMENT_STATE_UNSPECIFIED" /* EnforcementState.ENFORCEMENT_STATE_UNSPECIFIED */;
|
|
19320
|
+
}
|
|
19321
|
+
}
|
|
19227
19322
|
class NetworkTimeout {
|
|
19228
19323
|
constructor(auth) {
|
|
19229
19324
|
this.auth = auth;
|
|
@@ -19256,6 +19351,61 @@ function _makeTaggedError(auth, code, response) {
|
|
|
19256
19351
|
error.customData._tokenResponse = response;
|
|
19257
19352
|
return error;
|
|
19258
19353
|
}
|
|
19354
|
+
function isEnterprise(grecaptcha) {
|
|
19355
|
+
return (grecaptcha !== undefined &&
|
|
19356
|
+
grecaptcha.enterprise !== undefined);
|
|
19357
|
+
}
|
|
19358
|
+
class RecaptchaConfig {
|
|
19359
|
+
constructor(response) {
|
|
19360
|
+
/**
|
|
19361
|
+
* The reCAPTCHA site key.
|
|
19362
|
+
*/
|
|
19363
|
+
this.siteKey = '';
|
|
19364
|
+
/**
|
|
19365
|
+
* The list of providers and their enablement status for reCAPTCHA Enterprise.
|
|
19366
|
+
*/
|
|
19367
|
+
this.recaptchaEnforcementState = [];
|
|
19368
|
+
if (response.recaptchaKey === undefined) {
|
|
19369
|
+
throw new Error('recaptchaKey undefined');
|
|
19370
|
+
}
|
|
19371
|
+
// Example response.recaptchaKey: "projects/proj123/keys/sitekey123"
|
|
19372
|
+
this.siteKey = response.recaptchaKey.split('/')[3];
|
|
19373
|
+
this.recaptchaEnforcementState = response.recaptchaEnforcementState;
|
|
19374
|
+
}
|
|
19375
|
+
/**
|
|
19376
|
+
* Returns the reCAPTCHA Enterprise enforcement state for the given provider.
|
|
19377
|
+
*
|
|
19378
|
+
* @param providerStr - The provider whose enforcement state is to be returned.
|
|
19379
|
+
* @returns The reCAPTCHA Enterprise enforcement state for the given provider.
|
|
19380
|
+
*/
|
|
19381
|
+
getProviderEnforcementState(providerStr) {
|
|
19382
|
+
if (!this.recaptchaEnforcementState ||
|
|
19383
|
+
this.recaptchaEnforcementState.length === 0) {
|
|
19384
|
+
return null;
|
|
19385
|
+
}
|
|
19386
|
+
for (const recaptchaEnforcementState of this.recaptchaEnforcementState) {
|
|
19387
|
+
if (recaptchaEnforcementState.provider &&
|
|
19388
|
+
recaptchaEnforcementState.provider === providerStr) {
|
|
19389
|
+
return _parseEnforcementState(recaptchaEnforcementState.enforcementState);
|
|
19390
|
+
}
|
|
19391
|
+
}
|
|
19392
|
+
return null;
|
|
19393
|
+
}
|
|
19394
|
+
/**
|
|
19395
|
+
* Returns true if the reCAPTCHA Enterprise enforcement state for the provider is set to ENFORCE or AUDIT.
|
|
19396
|
+
*
|
|
19397
|
+
* @param providerStr - The provider whose enablement state is to be returned.
|
|
19398
|
+
* @returns Whether or not reCAPTCHA Enterprise protection is enabled for the given provider.
|
|
19399
|
+
*/
|
|
19400
|
+
isProviderEnabled(providerStr) {
|
|
19401
|
+
return (this.getProviderEnforcementState(providerStr) ===
|
|
19402
|
+
"ENFORCE" /* EnforcementState.ENFORCE */ ||
|
|
19403
|
+
this.getProviderEnforcementState(providerStr) === "AUDIT" /* EnforcementState.AUDIT */);
|
|
19404
|
+
}
|
|
19405
|
+
}
|
|
19406
|
+
async function getRecaptchaConfig(auth, request) {
|
|
19407
|
+
return _performApiRequest(auth, "GET" /* HttpMethod.GET */, "/v2/recaptchaConfig" /* Endpoint.GET_RECAPTCHA_CONFIG */, _addTidIfNecessary(auth, request));
|
|
19408
|
+
}
|
|
19259
19409
|
|
|
19260
19410
|
/**
|
|
19261
19411
|
* @license
|
|
@@ -19660,6 +19810,9 @@ async function requestStsToken(auth, refreshToken) {
|
|
|
19660
19810
|
expiresIn: response.expires_in,
|
|
19661
19811
|
refreshToken: response.refresh_token
|
|
19662
19812
|
};
|
|
19813
|
+
}
|
|
19814
|
+
async function revokeToken(auth, request) {
|
|
19815
|
+
return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v2/accounts:revokeToken" /* Endpoint.REVOKE_TOKEN */, _addTidIfNecessary(auth, request));
|
|
19663
19816
|
}
|
|
19664
19817
|
|
|
19665
19818
|
/**
|
|
@@ -19703,11 +19856,16 @@ class StsTokenManager {
|
|
|
19703
19856
|
: _tokenExpiresIn(response.idToken);
|
|
19704
19857
|
this.updateTokensAndExpiration(response.idToken, response.refreshToken, expiresIn);
|
|
19705
19858
|
}
|
|
19859
|
+
updateFromIdToken(idToken) {
|
|
19860
|
+
_assert(idToken.length !== 0, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
|
|
19861
|
+
const expiresIn = _tokenExpiresIn(idToken);
|
|
19862
|
+
this.updateTokensAndExpiration(idToken, null, expiresIn);
|
|
19863
|
+
}
|
|
19706
19864
|
async getToken(auth, forceRefresh = false) {
|
|
19707
|
-
_assert(!this.accessToken || this.refreshToken, auth, "user-token-expired" /* AuthErrorCode.TOKEN_EXPIRED */);
|
|
19708
19865
|
if (!forceRefresh && this.accessToken && !this.isExpired) {
|
|
19709
19866
|
return this.accessToken;
|
|
19710
19867
|
}
|
|
19868
|
+
_assert(this.refreshToken, auth, "user-token-expired" /* AuthErrorCode.TOKEN_EXPIRED */);
|
|
19711
19869
|
if (this.refreshToken) {
|
|
19712
19870
|
await this.refresh(auth, this.refreshToken);
|
|
19713
19871
|
return this.accessToken;
|
|
@@ -19887,6 +20045,9 @@ class UserImpl {
|
|
|
19887
20045
|
}
|
|
19888
20046
|
}
|
|
19889
20047
|
async delete() {
|
|
20048
|
+
if (_isFirebaseServerApp(this.auth.app)) {
|
|
20049
|
+
return Promise.reject(_serverAppCurrentUserOperationNotSupportedError(this.auth));
|
|
20050
|
+
}
|
|
19890
20051
|
const idToken = await this.getIdToken();
|
|
19891
20052
|
await _logoutIfInvalidated(this, deleteAccount(this.auth, { idToken }));
|
|
19892
20053
|
this.stsTokenManager.clearRefreshToken();
|
|
@@ -19970,6 +20131,44 @@ class UserImpl {
|
|
|
19970
20131
|
await _reloadWithoutSaving(user);
|
|
19971
20132
|
return user;
|
|
19972
20133
|
}
|
|
20134
|
+
/**
|
|
20135
|
+
* Initialize a User from an idToken server response
|
|
20136
|
+
* @param auth
|
|
20137
|
+
* @param idTokenResponse
|
|
20138
|
+
*/
|
|
20139
|
+
static async _fromGetAccountInfoResponse(auth, response, idToken) {
|
|
20140
|
+
const coreAccount = response.users[0];
|
|
20141
|
+
_assert(coreAccount.localId !== undefined, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
|
|
20142
|
+
const providerData = coreAccount.providerUserInfo !== undefined
|
|
20143
|
+
? extractProviderData(coreAccount.providerUserInfo)
|
|
20144
|
+
: [];
|
|
20145
|
+
const isAnonymous = !(coreAccount.email && coreAccount.passwordHash) && !(providerData === null || providerData === void 0 ? void 0 : providerData.length);
|
|
20146
|
+
const stsTokenManager = new StsTokenManager();
|
|
20147
|
+
stsTokenManager.updateFromIdToken(idToken);
|
|
20148
|
+
// Initialize the Firebase Auth user.
|
|
20149
|
+
const user = new UserImpl({
|
|
20150
|
+
uid: coreAccount.localId,
|
|
20151
|
+
auth,
|
|
20152
|
+
stsTokenManager,
|
|
20153
|
+
isAnonymous
|
|
20154
|
+
});
|
|
20155
|
+
// update the user with data from the GetAccountInfo response.
|
|
20156
|
+
const updates = {
|
|
20157
|
+
uid: coreAccount.localId,
|
|
20158
|
+
displayName: coreAccount.displayName || null,
|
|
20159
|
+
photoURL: coreAccount.photoUrl || null,
|
|
20160
|
+
email: coreAccount.email || null,
|
|
20161
|
+
emailVerified: coreAccount.emailVerified || false,
|
|
20162
|
+
phoneNumber: coreAccount.phoneNumber || null,
|
|
20163
|
+
tenantId: coreAccount.tenantId || null,
|
|
20164
|
+
providerData,
|
|
20165
|
+
metadata: new UserMetadata(coreAccount.createdAt, coreAccount.lastLoginAt),
|
|
20166
|
+
isAnonymous: !(coreAccount.email && coreAccount.passwordHash) &&
|
|
20167
|
+
!(providerData === null || providerData === void 0 ? void 0 : providerData.length)
|
|
20168
|
+
};
|
|
20169
|
+
Object.assign(user, updates);
|
|
20170
|
+
return user;
|
|
20171
|
+
}
|
|
19973
20172
|
}
|
|
19974
20173
|
|
|
19975
20174
|
/**
|
|
@@ -20285,16 +20484,6 @@ function _isMobileBrowser(ua = getUA()) {
|
|
|
20285
20484
|
_isBlackBerry(ua) ||
|
|
20286
20485
|
/windows phone/i.test(ua) ||
|
|
20287
20486
|
_isIEMobile(ua));
|
|
20288
|
-
}
|
|
20289
|
-
function _isIframe() {
|
|
20290
|
-
try {
|
|
20291
|
-
// Check that the current window is not the top window.
|
|
20292
|
-
// If so, return true.
|
|
20293
|
-
return !!(window && window !== window.top);
|
|
20294
|
-
}
|
|
20295
|
-
catch (e) {
|
|
20296
|
-
return false;
|
|
20297
|
-
}
|
|
20298
20487
|
}
|
|
20299
20488
|
|
|
20300
20489
|
/**
|
|
@@ -20337,36 +20526,91 @@ function _getClientVersion(clientPlatform, frameworks = []) {
|
|
|
20337
20526
|
: 'FirebaseCore-web'; /* default value if no other framework is used */
|
|
20338
20527
|
return `${reportedPlatform}/${"JsCore" /* ClientImplementation.CORE */}/${SDK_VERSION}/${reportedFrameworks}`;
|
|
20339
20528
|
}
|
|
20340
|
-
|
|
20341
|
-
|
|
20342
|
-
|
|
20343
|
-
|
|
20344
|
-
|
|
20345
|
-
|
|
20346
|
-
|
|
20347
|
-
|
|
20348
|
-
|
|
20349
|
-
|
|
20350
|
-
|
|
20351
|
-
|
|
20352
|
-
|
|
20353
|
-
|
|
20354
|
-
|
|
20355
|
-
|
|
20356
|
-
|
|
20357
|
-
|
|
20358
|
-
|
|
20529
|
+
|
|
20530
|
+
/**
|
|
20531
|
+
* @license
|
|
20532
|
+
* Copyright 2022 Google LLC
|
|
20533
|
+
*
|
|
20534
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
20535
|
+
* you may not use this file except in compliance with the License.
|
|
20536
|
+
* You may obtain a copy of the License at
|
|
20537
|
+
*
|
|
20538
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
20539
|
+
*
|
|
20540
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
20541
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
20542
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
20543
|
+
* See the License for the specific language governing permissions and
|
|
20544
|
+
* limitations under the License.
|
|
20545
|
+
*/
|
|
20546
|
+
class AuthMiddlewareQueue {
|
|
20547
|
+
constructor(auth) {
|
|
20548
|
+
this.auth = auth;
|
|
20549
|
+
this.queue = [];
|
|
20550
|
+
}
|
|
20551
|
+
pushCallback(callback, onAbort) {
|
|
20552
|
+
// The callback could be sync or async. Wrap it into a
|
|
20553
|
+
// function that is always async.
|
|
20554
|
+
const wrappedCallback = (user) => new Promise((resolve, reject) => {
|
|
20555
|
+
try {
|
|
20556
|
+
const result = callback(user);
|
|
20557
|
+
// Either resolve with existing promise or wrap a non-promise
|
|
20558
|
+
// return value into a promise.
|
|
20559
|
+
resolve(result);
|
|
20560
|
+
}
|
|
20561
|
+
catch (e) {
|
|
20562
|
+
// Sync callback throws.
|
|
20563
|
+
reject(e);
|
|
20564
|
+
}
|
|
20565
|
+
});
|
|
20566
|
+
// Attach the onAbort if present
|
|
20567
|
+
wrappedCallback.onAbort = onAbort;
|
|
20568
|
+
this.queue.push(wrappedCallback);
|
|
20569
|
+
const index = this.queue.length - 1;
|
|
20570
|
+
return () => {
|
|
20571
|
+
// Unsubscribe. Replace with no-op. Do not remove from array, or it will disturb
|
|
20572
|
+
// indexing of other elements.
|
|
20573
|
+
this.queue[index] = () => Promise.resolve();
|
|
20574
|
+
};
|
|
20575
|
+
}
|
|
20576
|
+
async runMiddleware(nextUser) {
|
|
20577
|
+
if (this.auth.currentUser === nextUser) {
|
|
20578
|
+
return;
|
|
20579
|
+
}
|
|
20580
|
+
// While running the middleware, build a temporary stack of onAbort
|
|
20581
|
+
// callbacks to call if one middleware callback rejects.
|
|
20582
|
+
const onAbortStack = [];
|
|
20583
|
+
try {
|
|
20584
|
+
for (const beforeStateCallback of this.queue) {
|
|
20585
|
+
await beforeStateCallback(nextUser);
|
|
20586
|
+
// Only push the onAbort if the callback succeeds
|
|
20587
|
+
if (beforeStateCallback.onAbort) {
|
|
20588
|
+
onAbortStack.push(beforeStateCallback.onAbort);
|
|
20589
|
+
}
|
|
20590
|
+
}
|
|
20591
|
+
}
|
|
20592
|
+
catch (e) {
|
|
20593
|
+
// Run all onAbort, with separate try/catch to ignore any errors and
|
|
20594
|
+
// continue
|
|
20595
|
+
onAbortStack.reverse();
|
|
20596
|
+
for (const onAbort of onAbortStack) {
|
|
20597
|
+
try {
|
|
20598
|
+
onAbort();
|
|
20599
|
+
}
|
|
20600
|
+
catch (_) {
|
|
20601
|
+
/* swallow error */
|
|
20602
|
+
}
|
|
20603
|
+
}
|
|
20604
|
+
throw this.auth._errorFactory.create("login-blocked" /* AuthErrorCode.LOGIN_BLOCKED */, {
|
|
20605
|
+
originalMessage: e === null || e === void 0 ? void 0 : e.message
|
|
20606
|
+
});
|
|
20359
20607
|
}
|
|
20360
|
-
// Example response.recaptchaKey: "projects/proj123/keys/sitekey123"
|
|
20361
|
-
this.siteKey = response.recaptchaKey.split('/')[3];
|
|
20362
|
-
this.emailPasswordEnabled = response.recaptchaEnforcementState.some(enforcementState => enforcementState.provider === 'EMAIL_PASSWORD_PROVIDER' &&
|
|
20363
|
-
enforcementState.enforcementState !== 'OFF');
|
|
20364
20608
|
}
|
|
20365
20609
|
}
|
|
20366
20610
|
|
|
20367
20611
|
/**
|
|
20368
20612
|
* @license
|
|
20369
|
-
* Copyright
|
|
20613
|
+
* Copyright 2023 Google LLC
|
|
20370
20614
|
*
|
|
20371
20615
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
20372
20616
|
* you may not use this file except in compliance with the License.
|
|
@@ -20380,232 +20624,162 @@ class RecaptchaConfig {
|
|
|
20380
20624
|
* See the License for the specific language governing permissions and
|
|
20381
20625
|
* limitations under the License.
|
|
20382
20626
|
*/
|
|
20383
|
-
|
|
20384
|
-
|
|
20385
|
-
|
|
20386
|
-
|
|
20387
|
-
|
|
20388
|
-
|
|
20389
|
-
|
|
20390
|
-
|
|
20391
|
-
|
|
20392
|
-
el.onload = resolve;
|
|
20393
|
-
el.onerror = e => {
|
|
20394
|
-
const error = _createError("internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
|
|
20395
|
-
error.customData = e;
|
|
20396
|
-
reject(error);
|
|
20397
|
-
};
|
|
20398
|
-
el.type = 'text/javascript';
|
|
20399
|
-
el.charset = 'UTF-8';
|
|
20400
|
-
getScriptParentElement().appendChild(el);
|
|
20401
|
-
});
|
|
20402
|
-
}
|
|
20403
|
-
function _generateCallbackName(prefix) {
|
|
20404
|
-
return `__${prefix}${Math.floor(Math.random() * 1000000)}`;
|
|
20627
|
+
/**
|
|
20628
|
+
* Fetches the password policy for the currently set tenant or the project if no tenant is set.
|
|
20629
|
+
*
|
|
20630
|
+
* @param auth Auth object.
|
|
20631
|
+
* @param request Password policy request.
|
|
20632
|
+
* @returns Password policy response.
|
|
20633
|
+
*/
|
|
20634
|
+
async function _getPasswordPolicy(auth, request = {}) {
|
|
20635
|
+
return _performApiRequest(auth, "GET" /* HttpMethod.GET */, "/v2/passwordPolicy" /* Endpoint.GET_PASSWORD_POLICY */, _addTidIfNecessary(auth, request));
|
|
20405
20636
|
}
|
|
20406
20637
|
|
|
20407
|
-
|
|
20408
|
-
|
|
20409
|
-
|
|
20410
|
-
|
|
20411
|
-
|
|
20638
|
+
/**
|
|
20639
|
+
* @license
|
|
20640
|
+
* Copyright 2023 Google LLC
|
|
20641
|
+
*
|
|
20642
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
20643
|
+
* you may not use this file except in compliance with the License.
|
|
20644
|
+
* You may obtain a copy of the License at
|
|
20645
|
+
*
|
|
20646
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
20647
|
+
*
|
|
20648
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
20649
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
20650
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
20651
|
+
* See the License for the specific language governing permissions and
|
|
20652
|
+
* limitations under the License.
|
|
20653
|
+
*/
|
|
20654
|
+
// Minimum min password length enforced by the backend, even if no minimum length is set.
|
|
20655
|
+
const MINIMUM_MIN_PASSWORD_LENGTH = 6;
|
|
20656
|
+
/**
|
|
20657
|
+
* Stores password policy requirements and provides password validation against the policy.
|
|
20658
|
+
*
|
|
20659
|
+
* @internal
|
|
20660
|
+
*/
|
|
20661
|
+
class PasswordPolicyImpl {
|
|
20662
|
+
constructor(response) {
|
|
20663
|
+
var _a, _b, _c, _d;
|
|
20664
|
+
// Only include custom strength options defined in the response.
|
|
20665
|
+
const responseOptions = response.customStrengthOptions;
|
|
20666
|
+
this.customStrengthOptions = {};
|
|
20667
|
+
// TODO: Remove once the backend is updated to include the minimum min password length instead of undefined when there is no minimum length set.
|
|
20668
|
+
this.customStrengthOptions.minPasswordLength =
|
|
20669
|
+
(_a = responseOptions.minPasswordLength) !== null && _a !== void 0 ? _a : MINIMUM_MIN_PASSWORD_LENGTH;
|
|
20670
|
+
if (responseOptions.maxPasswordLength) {
|
|
20671
|
+
this.customStrengthOptions.maxPasswordLength =
|
|
20672
|
+
responseOptions.maxPasswordLength;
|
|
20673
|
+
}
|
|
20674
|
+
if (responseOptions.containsLowercaseCharacter !== undefined) {
|
|
20675
|
+
this.customStrengthOptions.containsLowercaseLetter =
|
|
20676
|
+
responseOptions.containsLowercaseCharacter;
|
|
20677
|
+
}
|
|
20678
|
+
if (responseOptions.containsUppercaseCharacter !== undefined) {
|
|
20679
|
+
this.customStrengthOptions.containsUppercaseLetter =
|
|
20680
|
+
responseOptions.containsUppercaseCharacter;
|
|
20681
|
+
}
|
|
20682
|
+
if (responseOptions.containsNumericCharacter !== undefined) {
|
|
20683
|
+
this.customStrengthOptions.containsNumericCharacter =
|
|
20684
|
+
responseOptions.containsNumericCharacter;
|
|
20685
|
+
}
|
|
20686
|
+
if (responseOptions.containsNonAlphanumericCharacter !== undefined) {
|
|
20687
|
+
this.customStrengthOptions.containsNonAlphanumericCharacter =
|
|
20688
|
+
responseOptions.containsNonAlphanumericCharacter;
|
|
20689
|
+
}
|
|
20690
|
+
this.enforcementState = response.enforcementState;
|
|
20691
|
+
if (this.enforcementState === 'ENFORCEMENT_STATE_UNSPECIFIED') {
|
|
20692
|
+
this.enforcementState = 'OFF';
|
|
20693
|
+
}
|
|
20694
|
+
// Use an empty string if no non-alphanumeric characters are specified in the response.
|
|
20695
|
+
this.allowedNonAlphanumericCharacters =
|
|
20696
|
+
(_c = (_b = response.allowedNonAlphanumericCharacters) === null || _b === void 0 ? void 0 : _b.join('')) !== null && _c !== void 0 ? _c : '';
|
|
20697
|
+
this.forceUpgradeOnSignin = (_d = response.forceUpgradeOnSignin) !== null && _d !== void 0 ? _d : false;
|
|
20698
|
+
this.schemaVersion = response.schemaVersion;
|
|
20699
|
+
}
|
|
20700
|
+
validatePassword(password) {
|
|
20701
|
+
var _a, _b, _c, _d, _e, _f;
|
|
20702
|
+
const status = {
|
|
20703
|
+
isValid: true,
|
|
20704
|
+
passwordPolicy: this
|
|
20705
|
+
};
|
|
20706
|
+
// Check the password length and character options.
|
|
20707
|
+
this.validatePasswordLengthOptions(password, status);
|
|
20708
|
+
this.validatePasswordCharacterOptions(password, status);
|
|
20709
|
+
// Combine the status into single isValid property.
|
|
20710
|
+
status.isValid && (status.isValid = (_a = status.meetsMinPasswordLength) !== null && _a !== void 0 ? _a : true);
|
|
20711
|
+
status.isValid && (status.isValid = (_b = status.meetsMaxPasswordLength) !== null && _b !== void 0 ? _b : true);
|
|
20712
|
+
status.isValid && (status.isValid = (_c = status.containsLowercaseLetter) !== null && _c !== void 0 ? _c : true);
|
|
20713
|
+
status.isValid && (status.isValid = (_d = status.containsUppercaseLetter) !== null && _d !== void 0 ? _d : true);
|
|
20714
|
+
status.isValid && (status.isValid = (_e = status.containsNumericCharacter) !== null && _e !== void 0 ? _e : true);
|
|
20715
|
+
status.isValid && (status.isValid = (_f = status.containsNonAlphanumericCharacter) !== null && _f !== void 0 ? _f : true);
|
|
20716
|
+
return status;
|
|
20717
|
+
}
|
|
20412
20718
|
/**
|
|
20719
|
+
* Validates that the password meets the length options for the policy.
|
|
20413
20720
|
*
|
|
20414
|
-
* @param
|
|
20415
|
-
*
|
|
20721
|
+
* @param password Password to validate.
|
|
20722
|
+
* @param status Validation status.
|
|
20416
20723
|
*/
|
|
20417
|
-
|
|
20418
|
-
|
|
20419
|
-
|
|
20420
|
-
|
|
20421
|
-
|
|
20422
|
-
|
|
20724
|
+
validatePasswordLengthOptions(password, status) {
|
|
20725
|
+
const minPasswordLength = this.customStrengthOptions.minPasswordLength;
|
|
20726
|
+
const maxPasswordLength = this.customStrengthOptions.maxPasswordLength;
|
|
20727
|
+
if (minPasswordLength) {
|
|
20728
|
+
status.meetsMinPasswordLength = password.length >= minPasswordLength;
|
|
20729
|
+
}
|
|
20730
|
+
if (maxPasswordLength) {
|
|
20731
|
+
status.meetsMaxPasswordLength = password.length <= maxPasswordLength;
|
|
20732
|
+
}
|
|
20423
20733
|
}
|
|
20424
20734
|
/**
|
|
20425
|
-
*
|
|
20735
|
+
* Validates that the password meets the character options for the policy.
|
|
20426
20736
|
*
|
|
20427
|
-
* @
|
|
20737
|
+
* @param password Password to validate.
|
|
20738
|
+
* @param status Validation status.
|
|
20428
20739
|
*/
|
|
20429
|
-
|
|
20430
|
-
|
|
20431
|
-
|
|
20432
|
-
|
|
20433
|
-
|
|
20434
|
-
|
|
20435
|
-
|
|
20436
|
-
|
|
20437
|
-
|
|
20438
|
-
|
|
20439
|
-
|
|
20440
|
-
|
|
20441
|
-
|
|
20442
|
-
|
|
20443
|
-
|
|
20444
|
-
|
|
20445
|
-
|
|
20446
|
-
|
|
20447
|
-
reject(new Error('recaptcha Enterprise site key undefined'));
|
|
20448
|
-
}
|
|
20449
|
-
else {
|
|
20450
|
-
const config = new RecaptchaConfig(response);
|
|
20451
|
-
if (auth.tenantId == null) {
|
|
20452
|
-
auth._agentRecaptchaConfig = config;
|
|
20453
|
-
}
|
|
20454
|
-
else {
|
|
20455
|
-
auth._tenantRecaptchaConfigs[auth.tenantId] = config;
|
|
20456
|
-
}
|
|
20457
|
-
return resolve(config.siteKey);
|
|
20458
|
-
}
|
|
20459
|
-
})
|
|
20460
|
-
.catch(error => {
|
|
20461
|
-
reject(error);
|
|
20462
|
-
});
|
|
20463
|
-
});
|
|
20740
|
+
validatePasswordCharacterOptions(password, status) {
|
|
20741
|
+
// Assign statuses for requirements even if the password is an empty string.
|
|
20742
|
+
this.updatePasswordCharacterOptionsStatuses(status,
|
|
20743
|
+
/* containsLowercaseCharacter= */ false,
|
|
20744
|
+
/* containsUppercaseCharacter= */ false,
|
|
20745
|
+
/* containsNumericCharacter= */ false,
|
|
20746
|
+
/* containsNonAlphanumericCharacter= */ false);
|
|
20747
|
+
let passwordChar;
|
|
20748
|
+
for (let i = 0; i < password.length; i++) {
|
|
20749
|
+
passwordChar = password.charAt(i);
|
|
20750
|
+
this.updatePasswordCharacterOptionsStatuses(status,
|
|
20751
|
+
/* containsLowercaseCharacter= */ passwordChar >= 'a' &&
|
|
20752
|
+
passwordChar <= 'z',
|
|
20753
|
+
/* containsUppercaseCharacter= */ passwordChar >= 'A' &&
|
|
20754
|
+
passwordChar <= 'Z',
|
|
20755
|
+
/* containsNumericCharacter= */ passwordChar >= '0' &&
|
|
20756
|
+
passwordChar <= '9',
|
|
20757
|
+
/* containsNonAlphanumericCharacter= */ this.allowedNonAlphanumericCharacters.includes(passwordChar));
|
|
20464
20758
|
}
|
|
20465
|
-
function retrieveRecaptchaToken(siteKey, resolve, reject) {
|
|
20466
|
-
const grecaptcha = window.grecaptcha;
|
|
20467
|
-
if (isEnterprise(grecaptcha)) {
|
|
20468
|
-
grecaptcha.enterprise.ready(() => {
|
|
20469
|
-
grecaptcha.enterprise
|
|
20470
|
-
.execute(siteKey, { action })
|
|
20471
|
-
.then(token => {
|
|
20472
|
-
resolve(token);
|
|
20473
|
-
})
|
|
20474
|
-
.catch(() => {
|
|
20475
|
-
resolve(FAKE_TOKEN);
|
|
20476
|
-
});
|
|
20477
|
-
});
|
|
20478
|
-
}
|
|
20479
|
-
else {
|
|
20480
|
-
reject(Error('No reCAPTCHA enterprise script loaded.'));
|
|
20481
|
-
}
|
|
20482
|
-
}
|
|
20483
|
-
return new Promise((resolve, reject) => {
|
|
20484
|
-
retrieveSiteKey(this.auth)
|
|
20485
|
-
.then(siteKey => {
|
|
20486
|
-
if (!forceRefresh && isEnterprise(window.grecaptcha)) {
|
|
20487
|
-
retrieveRecaptchaToken(siteKey, resolve, reject);
|
|
20488
|
-
}
|
|
20489
|
-
else {
|
|
20490
|
-
if (typeof window === 'undefined') {
|
|
20491
|
-
reject(new Error('RecaptchaVerifier is only supported in browser'));
|
|
20492
|
-
return;
|
|
20493
|
-
}
|
|
20494
|
-
_loadJS(RECAPTCHA_ENTERPRISE_URL + siteKey)
|
|
20495
|
-
.then(() => {
|
|
20496
|
-
retrieveRecaptchaToken(siteKey, resolve, reject);
|
|
20497
|
-
})
|
|
20498
|
-
.catch(error => {
|
|
20499
|
-
reject(error);
|
|
20500
|
-
});
|
|
20501
|
-
}
|
|
20502
|
-
})
|
|
20503
|
-
.catch(error => {
|
|
20504
|
-
reject(error);
|
|
20505
|
-
});
|
|
20506
|
-
});
|
|
20507
|
-
}
|
|
20508
|
-
}
|
|
20509
|
-
async function injectRecaptchaFields(auth, request, action, captchaResp = false) {
|
|
20510
|
-
const verifier = new RecaptchaEnterpriseVerifier(auth);
|
|
20511
|
-
let captchaResponse;
|
|
20512
|
-
try {
|
|
20513
|
-
captchaResponse = await verifier.verify(action);
|
|
20514
|
-
}
|
|
20515
|
-
catch (error) {
|
|
20516
|
-
captchaResponse = await verifier.verify(action, true);
|
|
20517
|
-
}
|
|
20518
|
-
const newRequest = Object.assign({}, request);
|
|
20519
|
-
if (!captchaResp) {
|
|
20520
|
-
Object.assign(newRequest, { captchaResponse });
|
|
20521
|
-
}
|
|
20522
|
-
else {
|
|
20523
|
-
Object.assign(newRequest, { 'captchaResp': captchaResponse });
|
|
20524
|
-
}
|
|
20525
|
-
Object.assign(newRequest, { 'clientType': "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */ });
|
|
20526
|
-
Object.assign(newRequest, {
|
|
20527
|
-
'recaptchaVersion': "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
|
|
20528
|
-
});
|
|
20529
|
-
return newRequest;
|
|
20530
|
-
}
|
|
20531
|
-
|
|
20532
|
-
/**
|
|
20533
|
-
* @license
|
|
20534
|
-
* Copyright 2022 Google LLC
|
|
20535
|
-
*
|
|
20536
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
20537
|
-
* you may not use this file except in compliance with the License.
|
|
20538
|
-
* You may obtain a copy of the License at
|
|
20539
|
-
*
|
|
20540
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
20541
|
-
*
|
|
20542
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
20543
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
20544
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
20545
|
-
* See the License for the specific language governing permissions and
|
|
20546
|
-
* limitations under the License.
|
|
20547
|
-
*/
|
|
20548
|
-
class AuthMiddlewareQueue {
|
|
20549
|
-
constructor(auth) {
|
|
20550
|
-
this.auth = auth;
|
|
20551
|
-
this.queue = [];
|
|
20552
20759
|
}
|
|
20553
|
-
|
|
20554
|
-
|
|
20555
|
-
|
|
20556
|
-
|
|
20557
|
-
|
|
20558
|
-
|
|
20559
|
-
|
|
20560
|
-
|
|
20561
|
-
|
|
20562
|
-
|
|
20563
|
-
|
|
20564
|
-
|
|
20565
|
-
|
|
20566
|
-
|
|
20567
|
-
});
|
|
20568
|
-
// Attach the onAbort if present
|
|
20569
|
-
wrappedCallback.onAbort = onAbort;
|
|
20570
|
-
this.queue.push(wrappedCallback);
|
|
20571
|
-
const index = this.queue.length - 1;
|
|
20572
|
-
return () => {
|
|
20573
|
-
// Unsubscribe. Replace with no-op. Do not remove from array, or it will disturb
|
|
20574
|
-
// indexing of other elements.
|
|
20575
|
-
this.queue[index] = () => Promise.resolve();
|
|
20576
|
-
};
|
|
20577
|
-
}
|
|
20578
|
-
async runMiddleware(nextUser) {
|
|
20579
|
-
if (this.auth.currentUser === nextUser) {
|
|
20580
|
-
return;
|
|
20760
|
+
/**
|
|
20761
|
+
* Updates the running validation status with the statuses for the character options.
|
|
20762
|
+
* Expected to be called each time a character is processed to update each option status
|
|
20763
|
+
* based on the current character.
|
|
20764
|
+
*
|
|
20765
|
+
* @param status Validation status.
|
|
20766
|
+
* @param containsLowercaseCharacter Whether the character is a lowercase letter.
|
|
20767
|
+
* @param containsUppercaseCharacter Whether the character is an uppercase letter.
|
|
20768
|
+
* @param containsNumericCharacter Whether the character is a numeric character.
|
|
20769
|
+
* @param containsNonAlphanumericCharacter Whether the character is a non-alphanumeric character.
|
|
20770
|
+
*/
|
|
20771
|
+
updatePasswordCharacterOptionsStatuses(status, containsLowercaseCharacter, containsUppercaseCharacter, containsNumericCharacter, containsNonAlphanumericCharacter) {
|
|
20772
|
+
if (this.customStrengthOptions.containsLowercaseLetter) {
|
|
20773
|
+
status.containsLowercaseLetter || (status.containsLowercaseLetter = containsLowercaseCharacter);
|
|
20581
20774
|
}
|
|
20582
|
-
|
|
20583
|
-
|
|
20584
|
-
const onAbortStack = [];
|
|
20585
|
-
try {
|
|
20586
|
-
for (const beforeStateCallback of this.queue) {
|
|
20587
|
-
await beforeStateCallback(nextUser);
|
|
20588
|
-
// Only push the onAbort if the callback succeeds
|
|
20589
|
-
if (beforeStateCallback.onAbort) {
|
|
20590
|
-
onAbortStack.push(beforeStateCallback.onAbort);
|
|
20591
|
-
}
|
|
20592
|
-
}
|
|
20775
|
+
if (this.customStrengthOptions.containsUppercaseLetter) {
|
|
20776
|
+
status.containsUppercaseLetter || (status.containsUppercaseLetter = containsUppercaseCharacter);
|
|
20593
20777
|
}
|
|
20594
|
-
|
|
20595
|
-
|
|
20596
|
-
|
|
20597
|
-
|
|
20598
|
-
|
|
20599
|
-
try {
|
|
20600
|
-
onAbort();
|
|
20601
|
-
}
|
|
20602
|
-
catch (_) {
|
|
20603
|
-
/* swallow error */
|
|
20604
|
-
}
|
|
20605
|
-
}
|
|
20606
|
-
throw this.auth._errorFactory.create("login-blocked" /* AuthErrorCode.LOGIN_BLOCKED */, {
|
|
20607
|
-
originalMessage: e === null || e === void 0 ? void 0 : e.message
|
|
20608
|
-
});
|
|
20778
|
+
if (this.customStrengthOptions.containsNumericCharacter) {
|
|
20779
|
+
status.containsNumericCharacter || (status.containsNumericCharacter = containsNumericCharacter);
|
|
20780
|
+
}
|
|
20781
|
+
if (this.customStrengthOptions.containsNonAlphanumericCharacter) {
|
|
20782
|
+
status.containsNonAlphanumericCharacter || (status.containsNonAlphanumericCharacter = containsNonAlphanumericCharacter);
|
|
20609
20783
|
}
|
|
20610
20784
|
}
|
|
20611
20785
|
}
|
|
@@ -20640,6 +20814,7 @@ class AuthImpl {
|
|
|
20640
20814
|
this.beforeStateQueue = new AuthMiddlewareQueue(this);
|
|
20641
20815
|
this.redirectUser = null;
|
|
20642
20816
|
this.isProactiveRefreshEnabled = false;
|
|
20817
|
+
this.EXPECTED_PASSWORD_POLICY_SCHEMA_VERSION = 1;
|
|
20643
20818
|
// Any network calls will set this to true and prevent subsequent emulator
|
|
20644
20819
|
// initialization
|
|
20645
20820
|
this._canInitEmulator = true;
|
|
@@ -20650,6 +20825,8 @@ class AuthImpl {
|
|
|
20650
20825
|
this._errorFactory = _DEFAULT_AUTH_ERROR_FACTORY;
|
|
20651
20826
|
this._agentRecaptchaConfig = null;
|
|
20652
20827
|
this._tenantRecaptchaConfigs = {};
|
|
20828
|
+
this._projectPasswordPolicy = null;
|
|
20829
|
+
this._tenantPasswordPolicies = {};
|
|
20653
20830
|
// Tracks the last notified UID for state change listeners to prevent
|
|
20654
20831
|
// repeated calls to the callbacks. Undefined means it's never been
|
|
20655
20832
|
// called, whereas null means it's been called with a signed out user
|
|
@@ -20721,8 +20898,32 @@ class AuthImpl {
|
|
|
20721
20898
|
// Skip blocking callbacks, they should not apply to a change in another tab.
|
|
20722
20899
|
await this._updateCurrentUser(user, /* skipBeforeStateCallbacks */ true);
|
|
20723
20900
|
}
|
|
20901
|
+
async initializeCurrentUserFromIdToken(idToken) {
|
|
20902
|
+
try {
|
|
20903
|
+
const response = await getAccountInfo(this, { idToken });
|
|
20904
|
+
const user = await UserImpl._fromGetAccountInfoResponse(this, response, idToken);
|
|
20905
|
+
await this.directlySetCurrentUser(user);
|
|
20906
|
+
}
|
|
20907
|
+
catch (err) {
|
|
20908
|
+
console.warn('FirebaseServerApp could not login user with provided authIdToken: ', err);
|
|
20909
|
+
await this.directlySetCurrentUser(null);
|
|
20910
|
+
}
|
|
20911
|
+
}
|
|
20724
20912
|
async initializeCurrentUser(popupRedirectResolver) {
|
|
20725
20913
|
var _a;
|
|
20914
|
+
if (_isFirebaseServerApp(this.app)) {
|
|
20915
|
+
const idToken = this.app.settings.authIdToken;
|
|
20916
|
+
if (idToken) {
|
|
20917
|
+
// Start the auth operation in the next tick to allow a moment for the customer's app to
|
|
20918
|
+
// attach an emulator, if desired.
|
|
20919
|
+
return new Promise(resolve => {
|
|
20920
|
+
setTimeout(() => this.initializeCurrentUserFromIdToken(idToken).then(resolve, resolve));
|
|
20921
|
+
});
|
|
20922
|
+
}
|
|
20923
|
+
else {
|
|
20924
|
+
return this.directlySetCurrentUser(null);
|
|
20925
|
+
}
|
|
20926
|
+
}
|
|
20726
20927
|
// First check to see if we have a pending redirect event.
|
|
20727
20928
|
const previouslyStoredUser = (await this.assertedPersistence.getCurrentUser());
|
|
20728
20929
|
let futureCurrentUser = previouslyStoredUser;
|
|
@@ -20828,6 +21029,9 @@ class AuthImpl {
|
|
|
20828
21029
|
this._deleted = true;
|
|
20829
21030
|
}
|
|
20830
21031
|
async updateCurrentUser(userExtern) {
|
|
21032
|
+
if (_isFirebaseServerApp(this.app)) {
|
|
21033
|
+
return Promise.reject(_serverAppCurrentUserOperationNotSupportedError(this));
|
|
21034
|
+
}
|
|
20831
21035
|
// The public updateCurrentUser method needs to make a copy of the user,
|
|
20832
21036
|
// and also check that the project matches
|
|
20833
21037
|
const user = userExtern
|
|
@@ -20854,6 +21058,9 @@ class AuthImpl {
|
|
|
20854
21058
|
});
|
|
20855
21059
|
}
|
|
20856
21060
|
async signOut() {
|
|
21061
|
+
if (_isFirebaseServerApp(this.app)) {
|
|
21062
|
+
return Promise.reject(_serverAppCurrentUserOperationNotSupportedError(this));
|
|
21063
|
+
}
|
|
20857
21064
|
// Run first, to block _setRedirectUser() if any callbacks fail.
|
|
20858
21065
|
await this.beforeStateQueue.runMiddleware(null);
|
|
20859
21066
|
// Clear the redirect user when signOut is called
|
|
@@ -20865,33 +21072,51 @@ class AuthImpl {
|
|
|
20865
21072
|
return this._updateCurrentUser(null, /* skipBeforeStateCallbacks */ true);
|
|
20866
21073
|
}
|
|
20867
21074
|
setPersistence(persistence) {
|
|
21075
|
+
if (_isFirebaseServerApp(this.app)) {
|
|
21076
|
+
return Promise.reject(_serverAppCurrentUserOperationNotSupportedError(this));
|
|
21077
|
+
}
|
|
20868
21078
|
return this.queue(async () => {
|
|
20869
21079
|
await this.assertedPersistence.setPersistence(_getInstance(persistence));
|
|
20870
21080
|
});
|
|
20871
21081
|
}
|
|
20872
|
-
|
|
20873
|
-
const response = await getRecaptchaConfig(this, {
|
|
20874
|
-
clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */,
|
|
20875
|
-
version: "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
|
|
20876
|
-
});
|
|
20877
|
-
const config = new RecaptchaConfig(response);
|
|
21082
|
+
_getRecaptchaConfig() {
|
|
20878
21083
|
if (this.tenantId == null) {
|
|
20879
|
-
this._agentRecaptchaConfig
|
|
21084
|
+
return this._agentRecaptchaConfig;
|
|
20880
21085
|
}
|
|
20881
21086
|
else {
|
|
20882
|
-
this._tenantRecaptchaConfigs[this.tenantId]
|
|
21087
|
+
return this._tenantRecaptchaConfigs[this.tenantId];
|
|
21088
|
+
}
|
|
21089
|
+
}
|
|
21090
|
+
async validatePassword(password) {
|
|
21091
|
+
if (!this._getPasswordPolicyInternal()) {
|
|
21092
|
+
await this._updatePasswordPolicy();
|
|
20883
21093
|
}
|
|
20884
|
-
|
|
20885
|
-
|
|
20886
|
-
|
|
21094
|
+
// Password policy will be defined after fetching.
|
|
21095
|
+
const passwordPolicy = this._getPasswordPolicyInternal();
|
|
21096
|
+
// Check that the policy schema version is supported by the SDK.
|
|
21097
|
+
// TODO: Update this logic to use a max supported policy schema version once we have multiple schema versions.
|
|
21098
|
+
if (passwordPolicy.schemaVersion !==
|
|
21099
|
+
this.EXPECTED_PASSWORD_POLICY_SCHEMA_VERSION) {
|
|
21100
|
+
return Promise.reject(this._errorFactory.create("unsupported-password-policy-schema-version" /* AuthErrorCode.UNSUPPORTED_PASSWORD_POLICY_SCHEMA_VERSION */, {}));
|
|
20887
21101
|
}
|
|
21102
|
+
return passwordPolicy.validatePassword(password);
|
|
20888
21103
|
}
|
|
20889
|
-
|
|
20890
|
-
if (this.tenantId
|
|
20891
|
-
return this.
|
|
21104
|
+
_getPasswordPolicyInternal() {
|
|
21105
|
+
if (this.tenantId === null) {
|
|
21106
|
+
return this._projectPasswordPolicy;
|
|
20892
21107
|
}
|
|
20893
21108
|
else {
|
|
20894
|
-
return this.
|
|
21109
|
+
return this._tenantPasswordPolicies[this.tenantId];
|
|
21110
|
+
}
|
|
21111
|
+
}
|
|
21112
|
+
async _updatePasswordPolicy() {
|
|
21113
|
+
const response = await _getPasswordPolicy(this);
|
|
21114
|
+
const passwordPolicy = new PasswordPolicyImpl(response);
|
|
21115
|
+
if (this.tenantId === null) {
|
|
21116
|
+
this._projectPasswordPolicy = passwordPolicy;
|
|
21117
|
+
}
|
|
21118
|
+
else {
|
|
21119
|
+
this._tenantPasswordPolicies[this.tenantId] = passwordPolicy;
|
|
20895
21120
|
}
|
|
20896
21121
|
}
|
|
20897
21122
|
_getPersistence() {
|
|
@@ -20909,6 +21134,38 @@ class AuthImpl {
|
|
|
20909
21134
|
onIdTokenChanged(nextOrObserver, error, completed) {
|
|
20910
21135
|
return this.registerStateListener(this.idTokenSubscription, nextOrObserver, error, completed);
|
|
20911
21136
|
}
|
|
21137
|
+
authStateReady() {
|
|
21138
|
+
return new Promise((resolve, reject) => {
|
|
21139
|
+
if (this.currentUser) {
|
|
21140
|
+
resolve();
|
|
21141
|
+
}
|
|
21142
|
+
else {
|
|
21143
|
+
const unsubscribe = this.onAuthStateChanged(() => {
|
|
21144
|
+
unsubscribe();
|
|
21145
|
+
resolve();
|
|
21146
|
+
}, reject);
|
|
21147
|
+
}
|
|
21148
|
+
});
|
|
21149
|
+
}
|
|
21150
|
+
/**
|
|
21151
|
+
* Revokes the given access token. Currently only supports Apple OAuth access tokens.
|
|
21152
|
+
*/
|
|
21153
|
+
async revokeAccessToken(token) {
|
|
21154
|
+
if (this.currentUser) {
|
|
21155
|
+
const idToken = await this.currentUser.getIdToken();
|
|
21156
|
+
// Generalize this to accept other providers once supported.
|
|
21157
|
+
const request = {
|
|
21158
|
+
providerId: 'apple.com',
|
|
21159
|
+
tokenType: "ACCESS_TOKEN" /* TokenType.ACCESS_TOKEN */,
|
|
21160
|
+
token,
|
|
21161
|
+
idToken
|
|
21162
|
+
};
|
|
21163
|
+
if (this.tenantId != null) {
|
|
21164
|
+
request.tenantId = this.tenantId;
|
|
21165
|
+
}
|
|
21166
|
+
await revokeToken(this, request);
|
|
21167
|
+
}
|
|
21168
|
+
}
|
|
20912
21169
|
toJSON() {
|
|
20913
21170
|
var _a;
|
|
20914
21171
|
return {
|
|
@@ -20999,18 +21256,32 @@ class AuthImpl {
|
|
|
20999
21256
|
const cb = typeof nextOrObserver === 'function'
|
|
21000
21257
|
? nextOrObserver
|
|
21001
21258
|
: nextOrObserver.next.bind(nextOrObserver);
|
|
21259
|
+
let isUnsubscribed = false;
|
|
21002
21260
|
const promise = this._isInitialized
|
|
21003
21261
|
? Promise.resolve()
|
|
21004
21262
|
: this._initializationPromise;
|
|
21005
21263
|
_assert(promise, this, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
|
|
21006
21264
|
// The callback needs to be called asynchronously per the spec.
|
|
21007
21265
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
21008
|
-
promise.then(() =>
|
|
21266
|
+
promise.then(() => {
|
|
21267
|
+
if (isUnsubscribed) {
|
|
21268
|
+
return;
|
|
21269
|
+
}
|
|
21270
|
+
cb(this.currentUser);
|
|
21271
|
+
});
|
|
21009
21272
|
if (typeof nextOrObserver === 'function') {
|
|
21010
|
-
|
|
21273
|
+
const unsubscribe = subscription.addObserver(nextOrObserver, error, completed);
|
|
21274
|
+
return () => {
|
|
21275
|
+
isUnsubscribed = true;
|
|
21276
|
+
unsubscribe();
|
|
21277
|
+
};
|
|
21011
21278
|
}
|
|
21012
21279
|
else {
|
|
21013
|
-
|
|
21280
|
+
const unsubscribe = subscription.addObserver(nextOrObserver);
|
|
21281
|
+
return () => {
|
|
21282
|
+
isUnsubscribed = true;
|
|
21283
|
+
unsubscribe();
|
|
21284
|
+
};
|
|
21014
21285
|
}
|
|
21015
21286
|
}
|
|
21016
21287
|
/**
|
|
@@ -21095,7 +21366,7 @@ class AuthImpl {
|
|
|
21095
21366
|
}
|
|
21096
21367
|
}
|
|
21097
21368
|
/**
|
|
21098
|
-
* Method to be used to cast down to our private
|
|
21369
|
+
* Method to be used to cast down to our private implementation of Auth.
|
|
21099
21370
|
* It will also handle unwrapping from the compat type if necessary
|
|
21100
21371
|
*
|
|
21101
21372
|
* @param auth Auth object passed in from developer
|
|
@@ -21116,6 +21387,194 @@ class Subscription {
|
|
|
21116
21387
|
}
|
|
21117
21388
|
}
|
|
21118
21389
|
|
|
21390
|
+
/**
|
|
21391
|
+
* @license
|
|
21392
|
+
* Copyright 2020 Google LLC
|
|
21393
|
+
*
|
|
21394
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
21395
|
+
* you may not use this file except in compliance with the License.
|
|
21396
|
+
* You may obtain a copy of the License at
|
|
21397
|
+
*
|
|
21398
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
21399
|
+
*
|
|
21400
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
21401
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
21402
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
21403
|
+
* See the License for the specific language governing permissions and
|
|
21404
|
+
* limitations under the License.
|
|
21405
|
+
*/
|
|
21406
|
+
let externalJSProvider = {
|
|
21407
|
+
async loadJS() {
|
|
21408
|
+
throw new Error('Unable to load external scripts');
|
|
21409
|
+
},
|
|
21410
|
+
recaptchaV2Script: '',
|
|
21411
|
+
recaptchaEnterpriseScript: '',
|
|
21412
|
+
gapiScript: ''
|
|
21413
|
+
};
|
|
21414
|
+
function _setExternalJSProvider(p) {
|
|
21415
|
+
externalJSProvider = p;
|
|
21416
|
+
}
|
|
21417
|
+
function _loadJS(url) {
|
|
21418
|
+
return externalJSProvider.loadJS(url);
|
|
21419
|
+
}
|
|
21420
|
+
function _recaptchaEnterpriseScriptUrl() {
|
|
21421
|
+
return externalJSProvider.recaptchaEnterpriseScript;
|
|
21422
|
+
}
|
|
21423
|
+
function _gapiScriptUrl() {
|
|
21424
|
+
return externalJSProvider.gapiScript;
|
|
21425
|
+
}
|
|
21426
|
+
function _generateCallbackName(prefix) {
|
|
21427
|
+
return `__${prefix}${Math.floor(Math.random() * 1000000)}`;
|
|
21428
|
+
}
|
|
21429
|
+
|
|
21430
|
+
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
21431
|
+
const RECAPTCHA_ENTERPRISE_VERIFIER_TYPE = 'recaptcha-enterprise';
|
|
21432
|
+
const FAKE_TOKEN = 'NO_RECAPTCHA';
|
|
21433
|
+
class RecaptchaEnterpriseVerifier {
|
|
21434
|
+
/**
|
|
21435
|
+
*
|
|
21436
|
+
* @param authExtern - The corresponding Firebase {@link Auth} instance.
|
|
21437
|
+
*
|
|
21438
|
+
*/
|
|
21439
|
+
constructor(authExtern) {
|
|
21440
|
+
/**
|
|
21441
|
+
* Identifies the type of application verifier (e.g. "recaptcha-enterprise").
|
|
21442
|
+
*/
|
|
21443
|
+
this.type = RECAPTCHA_ENTERPRISE_VERIFIER_TYPE;
|
|
21444
|
+
this.auth = _castAuth(authExtern);
|
|
21445
|
+
}
|
|
21446
|
+
/**
|
|
21447
|
+
* Executes the verification process.
|
|
21448
|
+
*
|
|
21449
|
+
* @returns A Promise for a token that can be used to assert the validity of a request.
|
|
21450
|
+
*/
|
|
21451
|
+
async verify(action = 'verify', forceRefresh = false) {
|
|
21452
|
+
async function retrieveSiteKey(auth) {
|
|
21453
|
+
if (!forceRefresh) {
|
|
21454
|
+
if (auth.tenantId == null && auth._agentRecaptchaConfig != null) {
|
|
21455
|
+
return auth._agentRecaptchaConfig.siteKey;
|
|
21456
|
+
}
|
|
21457
|
+
if (auth.tenantId != null &&
|
|
21458
|
+
auth._tenantRecaptchaConfigs[auth.tenantId] !== undefined) {
|
|
21459
|
+
return auth._tenantRecaptchaConfigs[auth.tenantId].siteKey;
|
|
21460
|
+
}
|
|
21461
|
+
}
|
|
21462
|
+
return new Promise(async (resolve, reject) => {
|
|
21463
|
+
getRecaptchaConfig(auth, {
|
|
21464
|
+
clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */,
|
|
21465
|
+
version: "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
|
|
21466
|
+
})
|
|
21467
|
+
.then(response => {
|
|
21468
|
+
if (response.recaptchaKey === undefined) {
|
|
21469
|
+
reject(new Error('recaptcha Enterprise site key undefined'));
|
|
21470
|
+
}
|
|
21471
|
+
else {
|
|
21472
|
+
const config = new RecaptchaConfig(response);
|
|
21473
|
+
if (auth.tenantId == null) {
|
|
21474
|
+
auth._agentRecaptchaConfig = config;
|
|
21475
|
+
}
|
|
21476
|
+
else {
|
|
21477
|
+
auth._tenantRecaptchaConfigs[auth.tenantId] = config;
|
|
21478
|
+
}
|
|
21479
|
+
return resolve(config.siteKey);
|
|
21480
|
+
}
|
|
21481
|
+
})
|
|
21482
|
+
.catch(error => {
|
|
21483
|
+
reject(error);
|
|
21484
|
+
});
|
|
21485
|
+
});
|
|
21486
|
+
}
|
|
21487
|
+
function retrieveRecaptchaToken(siteKey, resolve, reject) {
|
|
21488
|
+
const grecaptcha = window.grecaptcha;
|
|
21489
|
+
if (isEnterprise(grecaptcha)) {
|
|
21490
|
+
grecaptcha.enterprise.ready(() => {
|
|
21491
|
+
grecaptcha.enterprise
|
|
21492
|
+
.execute(siteKey, { action })
|
|
21493
|
+
.then(token => {
|
|
21494
|
+
resolve(token);
|
|
21495
|
+
})
|
|
21496
|
+
.catch(() => {
|
|
21497
|
+
resolve(FAKE_TOKEN);
|
|
21498
|
+
});
|
|
21499
|
+
});
|
|
21500
|
+
}
|
|
21501
|
+
else {
|
|
21502
|
+
reject(Error('No reCAPTCHA enterprise script loaded.'));
|
|
21503
|
+
}
|
|
21504
|
+
}
|
|
21505
|
+
return new Promise((resolve, reject) => {
|
|
21506
|
+
retrieveSiteKey(this.auth)
|
|
21507
|
+
.then(siteKey => {
|
|
21508
|
+
if (!forceRefresh && isEnterprise(window.grecaptcha)) {
|
|
21509
|
+
retrieveRecaptchaToken(siteKey, resolve, reject);
|
|
21510
|
+
}
|
|
21511
|
+
else {
|
|
21512
|
+
if (typeof window === 'undefined') {
|
|
21513
|
+
reject(new Error('RecaptchaVerifier is only supported in browser'));
|
|
21514
|
+
return;
|
|
21515
|
+
}
|
|
21516
|
+
let url = _recaptchaEnterpriseScriptUrl();
|
|
21517
|
+
if (url.length !== 0) {
|
|
21518
|
+
url += siteKey;
|
|
21519
|
+
}
|
|
21520
|
+
_loadJS(url)
|
|
21521
|
+
.then(() => {
|
|
21522
|
+
retrieveRecaptchaToken(siteKey, resolve, reject);
|
|
21523
|
+
})
|
|
21524
|
+
.catch(error => {
|
|
21525
|
+
reject(error);
|
|
21526
|
+
});
|
|
21527
|
+
}
|
|
21528
|
+
})
|
|
21529
|
+
.catch(error => {
|
|
21530
|
+
reject(error);
|
|
21531
|
+
});
|
|
21532
|
+
});
|
|
21533
|
+
}
|
|
21534
|
+
}
|
|
21535
|
+
async function injectRecaptchaFields(auth, request, action, captchaResp = false) {
|
|
21536
|
+
const verifier = new RecaptchaEnterpriseVerifier(auth);
|
|
21537
|
+
let captchaResponse;
|
|
21538
|
+
try {
|
|
21539
|
+
captchaResponse = await verifier.verify(action);
|
|
21540
|
+
}
|
|
21541
|
+
catch (error) {
|
|
21542
|
+
captchaResponse = await verifier.verify(action, true);
|
|
21543
|
+
}
|
|
21544
|
+
const newRequest = Object.assign({}, request);
|
|
21545
|
+
if (!captchaResp) {
|
|
21546
|
+
Object.assign(newRequest, { captchaResponse });
|
|
21547
|
+
}
|
|
21548
|
+
else {
|
|
21549
|
+
Object.assign(newRequest, { 'captchaResp': captchaResponse });
|
|
21550
|
+
}
|
|
21551
|
+
Object.assign(newRequest, { 'clientType': "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */ });
|
|
21552
|
+
Object.assign(newRequest, {
|
|
21553
|
+
'recaptchaVersion': "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
|
|
21554
|
+
});
|
|
21555
|
+
return newRequest;
|
|
21556
|
+
}
|
|
21557
|
+
async function handleRecaptchaFlow(authInstance, request, actionName, actionMethod) {
|
|
21558
|
+
var _a;
|
|
21559
|
+
if ((_a = authInstance
|
|
21560
|
+
._getRecaptchaConfig()) === null || _a === void 0 ? void 0 : _a.isProviderEnabled("EMAIL_PASSWORD_PROVIDER" /* RecaptchaProvider.EMAIL_PASSWORD_PROVIDER */)) {
|
|
21561
|
+
const requestWithRecaptcha = await injectRecaptchaFields(authInstance, request, actionName, actionName === "getOobCode" /* RecaptchaActionName.GET_OOB_CODE */);
|
|
21562
|
+
return actionMethod(authInstance, requestWithRecaptcha);
|
|
21563
|
+
}
|
|
21564
|
+
else {
|
|
21565
|
+
return actionMethod(authInstance, request).catch(async (error) => {
|
|
21566
|
+
if (error.code === `auth/${"missing-recaptcha-token" /* AuthErrorCode.MISSING_RECAPTCHA_TOKEN */}`) {
|
|
21567
|
+
console.log(`${actionName} is protected by reCAPTCHA Enterprise for this project. Automatically triggering the reCAPTCHA flow and restarting the flow.`);
|
|
21568
|
+
const requestWithRecaptcha = await injectRecaptchaFields(authInstance, request, actionName, actionName === "getOobCode" /* RecaptchaActionName.GET_OOB_CODE */);
|
|
21569
|
+
return actionMethod(authInstance, requestWithRecaptcha);
|
|
21570
|
+
}
|
|
21571
|
+
else {
|
|
21572
|
+
return Promise.reject(error);
|
|
21573
|
+
}
|
|
21574
|
+
});
|
|
21575
|
+
}
|
|
21576
|
+
}
|
|
21577
|
+
|
|
21119
21578
|
/**
|
|
21120
21579
|
* @license
|
|
21121
21580
|
* Copyright 2020 Google LLC
|
|
@@ -21379,8 +21838,10 @@ class AuthCredential {
|
|
|
21379
21838
|
async function resetPassword(auth, request) {
|
|
21380
21839
|
return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:resetPassword" /* Endpoint.RESET_PASSWORD */, _addTidIfNecessary(auth, request));
|
|
21381
21840
|
}
|
|
21382
|
-
|
|
21383
|
-
|
|
21841
|
+
// Used for linking an email/password account to an existing idToken. Uses the same request/response
|
|
21842
|
+
// format as updateEmailPassword.
|
|
21843
|
+
async function linkEmailPassword(auth, request) {
|
|
21844
|
+
return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:signUp" /* Endpoint.SIGN_UP */, request);
|
|
21384
21845
|
}
|
|
21385
21846
|
|
|
21386
21847
|
/**
|
|
@@ -21511,7 +21972,6 @@ class EmailAuthCredential extends AuthCredential {
|
|
|
21511
21972
|
}
|
|
21512
21973
|
/** @internal */
|
|
21513
21974
|
async _getIdTokenResponse(auth) {
|
|
21514
|
-
var _a;
|
|
21515
21975
|
switch (this.signInMethod) {
|
|
21516
21976
|
case "password" /* SignInMethod.EMAIL_PASSWORD */:
|
|
21517
21977
|
const request = {
|
|
@@ -21520,22 +21980,7 @@ class EmailAuthCredential extends AuthCredential {
|
|
|
21520
21980
|
password: this._password,
|
|
21521
21981
|
clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */
|
|
21522
21982
|
};
|
|
21523
|
-
|
|
21524
|
-
const requestWithRecaptcha = await injectRecaptchaFields(auth, request, "signInWithPassword" /* RecaptchaActionName.SIGN_IN_WITH_PASSWORD */);
|
|
21525
|
-
return signInWithPassword(auth, requestWithRecaptcha);
|
|
21526
|
-
}
|
|
21527
|
-
else {
|
|
21528
|
-
return signInWithPassword(auth, request).catch(async (error) => {
|
|
21529
|
-
if (error.code === `auth/${"missing-recaptcha-token" /* AuthErrorCode.MISSING_RECAPTCHA_TOKEN */}`) {
|
|
21530
|
-
console.log('Sign-in with email address and password is protected by reCAPTCHA for this project. Automatically triggering the reCAPTCHA flow and restarting the sign-in flow.');
|
|
21531
|
-
const requestWithRecaptcha = await injectRecaptchaFields(auth, request, "signInWithPassword" /* RecaptchaActionName.SIGN_IN_WITH_PASSWORD */);
|
|
21532
|
-
return signInWithPassword(auth, requestWithRecaptcha);
|
|
21533
|
-
}
|
|
21534
|
-
else {
|
|
21535
|
-
return Promise.reject(error);
|
|
21536
|
-
}
|
|
21537
|
-
});
|
|
21538
|
-
}
|
|
21983
|
+
return handleRecaptchaFlow(auth, request, "signInWithPassword" /* RecaptchaActionName.SIGN_IN_WITH_PASSWORD */, signInWithPassword);
|
|
21539
21984
|
case "emailLink" /* SignInMethod.EMAIL_LINK */:
|
|
21540
21985
|
return signInWithEmailLink$1(auth, {
|
|
21541
21986
|
email: this._email,
|
|
@@ -21549,12 +21994,14 @@ class EmailAuthCredential extends AuthCredential {
|
|
|
21549
21994
|
async _linkToIdToken(auth, idToken) {
|
|
21550
21995
|
switch (this.signInMethod) {
|
|
21551
21996
|
case "password" /* SignInMethod.EMAIL_PASSWORD */:
|
|
21552
|
-
|
|
21997
|
+
const request = {
|
|
21553
21998
|
idToken,
|
|
21554
21999
|
returnSecureToken: true,
|
|
21555
22000
|
email: this._email,
|
|
21556
|
-
password: this._password
|
|
21557
|
-
|
|
22001
|
+
password: this._password,
|
|
22002
|
+
clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */
|
|
22003
|
+
};
|
|
22004
|
+
return handleRecaptchaFlow(auth, request, "signUpPassword" /* RecaptchaActionName.SIGN_UP_PASSWORD */, linkEmailPassword);
|
|
21558
22005
|
case "emailLink" /* SignInMethod.EMAIL_LINK */:
|
|
21559
22006
|
return signInWithEmailLinkForLinking(auth, {
|
|
21560
22007
|
idToken,
|
|
@@ -22172,7 +22619,7 @@ FacebookAuthProvider.PROVIDER_ID = "facebook.com" /* ProviderId.FACEBOOK */;
|
|
|
22172
22619
|
* limitations under the License.
|
|
22173
22620
|
*/
|
|
22174
22621
|
/**
|
|
22175
|
-
* Provider for generating an
|
|
22622
|
+
* Provider for generating an {@link OAuthCredential} for {@link ProviderId}.GOOGLE.
|
|
22176
22623
|
*
|
|
22177
22624
|
* @example
|
|
22178
22625
|
* ```javascript
|
|
@@ -22314,7 +22761,7 @@ GoogleAuthProvider.PROVIDER_ID = "google.com" /* ProviderId.GOOGLE */;
|
|
|
22314
22761
|
* if (result) {
|
|
22315
22762
|
* // This is the signed-in user
|
|
22316
22763
|
* const user = result.user;
|
|
22317
|
-
* // This gives you a
|
|
22764
|
+
* // This gives you a GitHub Access Token.
|
|
22318
22765
|
* const credential = GithubAuthProvider.credentialFromResult(result);
|
|
22319
22766
|
* const token = credential.accessToken;
|
|
22320
22767
|
* }
|
|
@@ -22329,7 +22776,7 @@ GoogleAuthProvider.PROVIDER_ID = "google.com" /* ProviderId.GOOGLE */;
|
|
|
22329
22776
|
*
|
|
22330
22777
|
* // The signed-in user info.
|
|
22331
22778
|
* const user = result.user;
|
|
22332
|
-
* // This gives you a
|
|
22779
|
+
* // This gives you a GitHub Access Token.
|
|
22333
22780
|
* const credential = GithubAuthProvider.credentialFromResult(result);
|
|
22334
22781
|
* const token = credential.accessToken;
|
|
22335
22782
|
* ```
|
|
@@ -22340,9 +22787,9 @@ class GithubAuthProvider extends BaseOAuthProvider {
|
|
|
22340
22787
|
super("github.com" /* ProviderId.GITHUB */);
|
|
22341
22788
|
}
|
|
22342
22789
|
/**
|
|
22343
|
-
* Creates a credential for
|
|
22790
|
+
* Creates a credential for GitHub.
|
|
22344
22791
|
*
|
|
22345
|
-
* @param accessToken -
|
|
22792
|
+
* @param accessToken - GitHub access token.
|
|
22346
22793
|
*/
|
|
22347
22794
|
static credential(accessToken) {
|
|
22348
22795
|
return OAuthCredential._fromParams({
|
|
@@ -22623,6 +23070,9 @@ async function _link$1(user, credential, bypassAuthState = false) {
|
|
|
22623
23070
|
*/
|
|
22624
23071
|
async function _reauthenticate(user, credential, bypassAuthState = false) {
|
|
22625
23072
|
const { auth } = user;
|
|
23073
|
+
if (_isFirebaseServerApp(auth.app)) {
|
|
23074
|
+
return Promise.reject(_serverAppCurrentUserOperationNotSupportedError(auth));
|
|
23075
|
+
}
|
|
22626
23076
|
const operationType = "reauthenticate" /* OperationType.REAUTHENTICATE */;
|
|
22627
23077
|
try {
|
|
22628
23078
|
const response = await _logoutIfInvalidated(user, _processCredentialSavingMfaContextIfNecessary(auth, operationType, credential, user), bypassAuthState);
|
|
@@ -22659,6 +23109,9 @@ async function _reauthenticate(user, credential, bypassAuthState = false) {
|
|
|
22659
23109
|
* limitations under the License.
|
|
22660
23110
|
*/
|
|
22661
23111
|
async function _signInWithCredential(auth, credential, bypassAuthState = false) {
|
|
23112
|
+
if (_isFirebaseServerApp(auth.app)) {
|
|
23113
|
+
return Promise.reject(_serverAppCurrentUserOperationNotSupportedError(auth));
|
|
23114
|
+
}
|
|
22662
23115
|
const operationType = "signIn" /* OperationType.SIGN_IN */;
|
|
22663
23116
|
const response = await _processCredentialSavingMfaContextIfNecessary(auth, operationType, credential);
|
|
22664
23117
|
const userCredential = await UserCredentialImpl._fromIdTokenResponse(auth, operationType, response);
|
|
@@ -22673,6 +23126,9 @@ async function _signInWithCredential(auth, credential, bypassAuthState = false)
|
|
|
22673
23126
|
* @remarks
|
|
22674
23127
|
* An {@link AuthProvider} can be used to generate the credential.
|
|
22675
23128
|
*
|
|
23129
|
+
* This method is not supported by {@link Auth} instances created with a
|
|
23130
|
+
* {@link @firebase/app#FirebaseServerApp}.
|
|
23131
|
+
*
|
|
22676
23132
|
* @param auth - The {@link Auth} instance.
|
|
22677
23133
|
* @param credential - The auth credential.
|
|
22678
23134
|
*
|
|
@@ -22736,7 +23192,29 @@ function _setActionCodeSettingsOnRequest(auth, request, actionCodeSettings) {
|
|
|
22736
23192
|
* limitations under the License.
|
|
22737
23193
|
*/
|
|
22738
23194
|
/**
|
|
22739
|
-
*
|
|
23195
|
+
* Updates the password policy cached in the {@link Auth} instance if a policy is already
|
|
23196
|
+
* cached for the project or tenant.
|
|
23197
|
+
*
|
|
23198
|
+
* @remarks
|
|
23199
|
+
* We only fetch the password policy if the password did not meet policy requirements and
|
|
23200
|
+
* there is an existing policy cached. A developer must call validatePassword at least
|
|
23201
|
+
* once for the cache to be automatically updated.
|
|
23202
|
+
*
|
|
23203
|
+
* @param auth - The {@link Auth} instance.
|
|
23204
|
+
*
|
|
23205
|
+
* @private
|
|
23206
|
+
*/
|
|
23207
|
+
async function recachePasswordPolicy(auth) {
|
|
23208
|
+
const authInternal = _castAuth(auth);
|
|
23209
|
+
if (authInternal._getPasswordPolicyInternal()) {
|
|
23210
|
+
await authInternal._updatePasswordPolicy();
|
|
23211
|
+
}
|
|
23212
|
+
}
|
|
23213
|
+
/**
|
|
23214
|
+
* Sends a password reset email to the given email address. This method does not throw an error when
|
|
23215
|
+
* there's no user account with the given email address and
|
|
23216
|
+
* {@link https://cloud.google.com/identity-platform/docs/admin/email-enumeration-protection | Email Enumeration Protection}
|
|
23217
|
+
* is enabled.
|
|
22740
23218
|
*
|
|
22741
23219
|
* @remarks
|
|
22742
23220
|
* To complete the password reset, call {@link confirmPasswordReset} with the code supplied in
|
|
@@ -22768,39 +23246,16 @@ function _setActionCodeSettingsOnRequest(auth, request, actionCodeSettings) {
|
|
|
22768
23246
|
* @public
|
|
22769
23247
|
*/
|
|
22770
23248
|
async function sendPasswordResetEmail(auth, email, actionCodeSettings) {
|
|
22771
|
-
var _a;
|
|
22772
23249
|
const authInternal = _castAuth(auth);
|
|
22773
23250
|
const request = {
|
|
22774
23251
|
requestType: "PASSWORD_RESET" /* ActionCodeOperation.PASSWORD_RESET */,
|
|
22775
23252
|
email,
|
|
22776
23253
|
clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */
|
|
22777
23254
|
};
|
|
22778
|
-
if (
|
|
22779
|
-
|
|
22780
|
-
if (actionCodeSettings) {
|
|
22781
|
-
_setActionCodeSettingsOnRequest(authInternal, requestWithRecaptcha, actionCodeSettings);
|
|
22782
|
-
}
|
|
22783
|
-
await sendPasswordResetEmail$1(authInternal, requestWithRecaptcha);
|
|
22784
|
-
}
|
|
22785
|
-
else {
|
|
22786
|
-
if (actionCodeSettings) {
|
|
22787
|
-
_setActionCodeSettingsOnRequest(authInternal, request, actionCodeSettings);
|
|
22788
|
-
}
|
|
22789
|
-
await sendPasswordResetEmail$1(authInternal, request)
|
|
22790
|
-
.catch(async (error) => {
|
|
22791
|
-
if (error.code === `auth/${"missing-recaptcha-token" /* AuthErrorCode.MISSING_RECAPTCHA_TOKEN */}`) {
|
|
22792
|
-
console.log('Password resets are protected by reCAPTCHA for this project. Automatically triggering the reCAPTCHA flow and restarting the password reset flow.');
|
|
22793
|
-
const requestWithRecaptcha = await injectRecaptchaFields(authInternal, request, "getOobCode" /* RecaptchaActionName.GET_OOB_CODE */, true);
|
|
22794
|
-
if (actionCodeSettings) {
|
|
22795
|
-
_setActionCodeSettingsOnRequest(authInternal, requestWithRecaptcha, actionCodeSettings);
|
|
22796
|
-
}
|
|
22797
|
-
await sendPasswordResetEmail$1(authInternal, requestWithRecaptcha);
|
|
22798
|
-
}
|
|
22799
|
-
else {
|
|
22800
|
-
return Promise.reject(error);
|
|
22801
|
-
}
|
|
22802
|
-
});
|
|
23255
|
+
if (actionCodeSettings) {
|
|
23256
|
+
_setActionCodeSettingsOnRequest(authInternal, request, actionCodeSettings);
|
|
22803
23257
|
}
|
|
23258
|
+
await handleRecaptchaFlow(authInternal, request, "getOobCode" /* RecaptchaActionName.GET_OOB_CODE */, sendPasswordResetEmail$1);
|
|
22804
23259
|
}
|
|
22805
23260
|
/**
|
|
22806
23261
|
* Completes the password reset process, given a confirmation code and new password.
|
|
@@ -22815,6 +23270,13 @@ async function confirmPasswordReset(auth, oobCode, newPassword) {
|
|
|
22815
23270
|
await resetPassword(getModularInstance$1(auth), {
|
|
22816
23271
|
oobCode,
|
|
22817
23272
|
newPassword
|
|
23273
|
+
})
|
|
23274
|
+
.catch(async (error) => {
|
|
23275
|
+
if (error.code ===
|
|
23276
|
+
`auth/${"password-does-not-meet-requirements" /* AuthErrorCode.PASSWORD_DOES_NOT_MEET_REQUIREMENTS */}`) {
|
|
23277
|
+
void recachePasswordPolicy(auth);
|
|
23278
|
+
}
|
|
23279
|
+
throw error;
|
|
22818
23280
|
});
|
|
22819
23281
|
// Do not return the email.
|
|
22820
23282
|
}
|
|
@@ -22822,12 +23284,19 @@ async function confirmPasswordReset(auth, oobCode, newPassword) {
|
|
|
22822
23284
|
* Asynchronously signs in using an email and password.
|
|
22823
23285
|
*
|
|
22824
23286
|
* @remarks
|
|
22825
|
-
* Fails with an error if the email address and password do not match.
|
|
23287
|
+
* Fails with an error if the email address and password do not match. When
|
|
23288
|
+
* {@link https://cloud.google.com/identity-platform/docs/admin/email-enumeration-protection | Email Enumeration Protection}
|
|
23289
|
+
* is enabled, this method fails with "auth/invalid-credential" in case of an invalid
|
|
23290
|
+
* email/password.
|
|
23291
|
+
*
|
|
23292
|
+
* This method is not supported on {@link Auth} instances created with a
|
|
23293
|
+
* {@link @firebase/app#FirebaseServerApp}.
|
|
22826
23294
|
*
|
|
22827
23295
|
* Note: The user's password is NOT the password used to access the user's email account. The
|
|
22828
23296
|
* email address serves as a unique identifier for the user, and the password is used to access
|
|
22829
23297
|
* the user's account in your Firebase project. See also: {@link createUserWithEmailAndPassword}.
|
|
22830
23298
|
*
|
|
23299
|
+
*
|
|
22831
23300
|
* @param auth - The {@link Auth} instance.
|
|
22832
23301
|
* @param email - The users email address.
|
|
22833
23302
|
* @param password - The users password.
|
|
@@ -22835,7 +23304,15 @@ async function confirmPasswordReset(auth, oobCode, newPassword) {
|
|
|
22835
23304
|
* @public
|
|
22836
23305
|
*/
|
|
22837
23306
|
function signInWithEmailAndPassword(auth, email, password) {
|
|
22838
|
-
|
|
23307
|
+
if (_isFirebaseServerApp(auth.app)) {
|
|
23308
|
+
return Promise.reject(_serverAppCurrentUserOperationNotSupportedError(auth));
|
|
23309
|
+
}
|
|
23310
|
+
return signInWithCredential(getModularInstance$1(auth), EmailAuthProvider.credential(email, password)).catch(async (error) => {
|
|
23311
|
+
if (error.code === `auth/${"password-does-not-meet-requirements" /* AuthErrorCode.PASSWORD_DOES_NOT_MEET_REQUIREMENTS */}`) {
|
|
23312
|
+
void recachePasswordPolicy(auth);
|
|
23313
|
+
}
|
|
23314
|
+
throw error;
|
|
23315
|
+
});
|
|
22839
23316
|
}
|
|
22840
23317
|
/**
|
|
22841
23318
|
* Adds an observer for changes to the signed-in user's ID token.
|
|
@@ -22942,10 +23419,6 @@ class BrowserPersistenceClass {
|
|
|
22942
23419
|
* See the License for the specific language governing permissions and
|
|
22943
23420
|
* limitations under the License.
|
|
22944
23421
|
*/
|
|
22945
|
-
function _iframeCannotSyncWebStorage() {
|
|
22946
|
-
const ua = getUA();
|
|
22947
|
-
return _isSafari(ua) || _isIOS(ua);
|
|
22948
|
-
}
|
|
22949
23422
|
// The polling period in case events are not supported
|
|
22950
23423
|
const _POLLING_INTERVAL_MS$1 = 1000;
|
|
22951
23424
|
// The IE 10 localStorage cross tab synchronization delay in milliseconds
|
|
@@ -22959,8 +23432,6 @@ class BrowserLocalPersistence extends BrowserPersistenceClass {
|
|
|
22959
23432
|
// setTimeout return value is platform specific
|
|
22960
23433
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22961
23434
|
this.pollTimer = null;
|
|
22962
|
-
// Safari or iOS browser and embedded in an iframe.
|
|
22963
|
-
this.safariLocalStorageNotSynced = _iframeCannotSyncWebStorage() && _isIframe();
|
|
22964
23435
|
// Whether to use polling instead of depending on window events
|
|
22965
23436
|
this.fallbackToPolling = _isMobileBrowser();
|
|
22966
23437
|
this._shouldAllowMigration = true;
|
|
@@ -22999,27 +23470,6 @@ class BrowserLocalPersistence extends BrowserPersistenceClass {
|
|
|
22999
23470
|
// Remove polling listener to prevent possible event duplication.
|
|
23000
23471
|
this.stopPolling();
|
|
23001
23472
|
}
|
|
23002
|
-
// Safari embedded iframe. Storage event will trigger with the delta
|
|
23003
|
-
// changes but no changes will be applied to the iframe localStorage.
|
|
23004
|
-
if (this.safariLocalStorageNotSynced) {
|
|
23005
|
-
// Get current iframe page value.
|
|
23006
|
-
const storedValue = this.storage.getItem(key);
|
|
23007
|
-
// Value not synchronized, synchronize manually.
|
|
23008
|
-
if (event.newValue !== storedValue) {
|
|
23009
|
-
if (event.newValue !== null) {
|
|
23010
|
-
// Value changed from current value.
|
|
23011
|
-
this.storage.setItem(key, event.newValue);
|
|
23012
|
-
}
|
|
23013
|
-
else {
|
|
23014
|
-
// Current value deleted.
|
|
23015
|
-
this.storage.removeItem(key);
|
|
23016
|
-
}
|
|
23017
|
-
}
|
|
23018
|
-
else if (this.localCache[key] === event.newValue && !poll) {
|
|
23019
|
-
// Already detected and processed, do not trigger listeners again.
|
|
23020
|
-
return;
|
|
23021
|
-
}
|
|
23022
|
-
}
|
|
23023
23473
|
const triggerListeners = () => {
|
|
23024
23474
|
// Keep local map up to date in case storage event is triggered before
|
|
23025
23475
|
// poll.
|
|
@@ -23310,7 +23760,7 @@ class Receiver {
|
|
|
23310
23760
|
* Unsubscribe an event handler from a particular event.
|
|
23311
23761
|
*
|
|
23312
23762
|
* @param eventType - Event name to unsubscribe from.
|
|
23313
|
-
* @param eventHandler -
|
|
23763
|
+
* @param eventHandler - Optional event handler, if none provided, unsubscribe all handlers on this event.
|
|
23314
23764
|
*
|
|
23315
23765
|
*/
|
|
23316
23766
|
_unsubscribe(eventType, eventHandler) {
|
|
@@ -23804,11 +24254,13 @@ class IndexedDBLocalPersistence {
|
|
|
23804
24254
|
}
|
|
23805
24255
|
const keys = [];
|
|
23806
24256
|
const keysInResult = new Set();
|
|
23807
|
-
|
|
23808
|
-
|
|
23809
|
-
|
|
23810
|
-
this.
|
|
23811
|
-
|
|
24257
|
+
if (result.length !== 0) {
|
|
24258
|
+
for (const { fbase_key: key, value } of result) {
|
|
24259
|
+
keysInResult.add(key);
|
|
24260
|
+
if (JSON.stringify(this.localCache[key]) !== JSON.stringify(value)) {
|
|
24261
|
+
this.notifyListeners(key, value);
|
|
24262
|
+
keys.push(key);
|
|
24263
|
+
}
|
|
23812
24264
|
}
|
|
23813
24265
|
}
|
|
23814
24266
|
for (const localKey of Object.keys(this.localCache)) {
|
|
@@ -24264,6 +24716,9 @@ function pendingRedirectKey(auth) {
|
|
|
24264
24716
|
return _persistenceKeyName(PENDING_REDIRECT_KEY, auth.config.apiKey, auth.name);
|
|
24265
24717
|
}
|
|
24266
24718
|
async function _getRedirectResult(auth, resolverExtern, bypassAuthState = false) {
|
|
24719
|
+
if (_isFirebaseServerApp(auth.app)) {
|
|
24720
|
+
return Promise.reject(_serverAppCurrentUserOperationNotSupportedError(auth));
|
|
24721
|
+
}
|
|
24267
24722
|
const authInternal = _castAuth(auth);
|
|
24268
24723
|
const resolver = _withDefaultResolver(authInternal, resolverExtern);
|
|
24269
24724
|
const action = new RedirectAction(authInternal, resolver, bypassAuthState);
|
|
@@ -24494,7 +24949,7 @@ function matchDomain(expected) {
|
|
|
24494
24949
|
*/
|
|
24495
24950
|
const NETWORK_TIMEOUT = new Delay(30000, 60000);
|
|
24496
24951
|
/**
|
|
24497
|
-
* Reset
|
|
24952
|
+
* Reset unloaded GApi modules. If gapi.load fails due to a network error,
|
|
24498
24953
|
* it will stop working after a retrial. This is a hack to fix this issue.
|
|
24499
24954
|
*/
|
|
24500
24955
|
function resetUnloadedGapiModules() {
|
|
@@ -24574,7 +25029,7 @@ function loadGapi(auth) {
|
|
|
24574
25029
|
}
|
|
24575
25030
|
};
|
|
24576
25031
|
// Load GApi loader.
|
|
24577
|
-
return _loadJS(
|
|
25032
|
+
return _loadJS(`${_gapiScriptUrl()}?onload=${cbName}`)
|
|
24578
25033
|
.catch(e => reject(e));
|
|
24579
25034
|
}
|
|
24580
25035
|
}).catch(error => {
|
|
@@ -24829,7 +25284,7 @@ async function _getRedirectUrl(auth, provider, authType, redirectUrl, eventId, a
|
|
|
24829
25284
|
if (auth.tenantId) {
|
|
24830
25285
|
params.tid = auth.tenantId;
|
|
24831
25286
|
}
|
|
24832
|
-
// TODO: maybe set eid as
|
|
25287
|
+
// TODO: maybe set eid as endpointId
|
|
24833
25288
|
// TODO: maybe set fw as Frameworks.join(",")
|
|
24834
25289
|
const paramsDict = params;
|
|
24835
25290
|
for (const key of Object.keys(paramsDict)) {
|
|
@@ -24957,12 +25412,15 @@ class BrowserPopupRedirectResolver {
|
|
|
24957
25412
|
* An implementation of {@link PopupRedirectResolver} suitable for browser
|
|
24958
25413
|
* based applications.
|
|
24959
25414
|
*
|
|
25415
|
+
* @remarks
|
|
25416
|
+
* This method does not work in a Node.js environment.
|
|
25417
|
+
*
|
|
24960
25418
|
* @public
|
|
24961
25419
|
*/
|
|
24962
25420
|
const browserPopupRedirectResolver = BrowserPopupRedirectResolver;
|
|
24963
25421
|
|
|
24964
25422
|
var name = "@firebase/auth";
|
|
24965
|
-
var version = "
|
|
25423
|
+
var version = "1.7.7";
|
|
24966
25424
|
|
|
24967
25425
|
/**
|
|
24968
25426
|
* @license
|
|
@@ -25059,6 +25517,8 @@ function getVersionForPlatform(clientPlatform) {
|
|
|
25059
25517
|
return 'webworker';
|
|
25060
25518
|
case "Cordova" /* ClientPlatform.CORDOVA */:
|
|
25061
25519
|
return 'cordova';
|
|
25520
|
+
case "WebExtension" /* ClientPlatform.WEB_EXTENSION */:
|
|
25521
|
+
return 'web-extension';
|
|
25062
25522
|
default:
|
|
25063
25523
|
return undefined;
|
|
25064
25524
|
}
|
|
@@ -25168,11 +25628,18 @@ function getAuth(app = getApp()) {
|
|
|
25168
25628
|
browserSessionPersistence
|
|
25169
25629
|
]
|
|
25170
25630
|
});
|
|
25171
|
-
const
|
|
25172
|
-
|
|
25173
|
-
|
|
25174
|
-
|
|
25175
|
-
|
|
25631
|
+
const authTokenSyncPath = getExperimentalSetting('authTokenSyncURL');
|
|
25632
|
+
// Only do the Cookie exchange in a secure context
|
|
25633
|
+
if (authTokenSyncPath &&
|
|
25634
|
+
typeof isSecureContext === 'boolean' &&
|
|
25635
|
+
isSecureContext) {
|
|
25636
|
+
// Don't allow urls (XSS possibility), only paths on the same domain
|
|
25637
|
+
const authTokenSyncUrl = new URL(authTokenSyncPath, location.origin);
|
|
25638
|
+
if (location.origin === authTokenSyncUrl.origin) {
|
|
25639
|
+
const mintCookie = mintCookieFactory(authTokenSyncUrl.toString());
|
|
25640
|
+
beforeAuthStateChanged(auth, mintCookie, () => mintCookie(auth.currentUser));
|
|
25641
|
+
onIdTokenChanged(auth, user => mintCookie(user));
|
|
25642
|
+
}
|
|
25176
25643
|
}
|
|
25177
25644
|
const authEmulatorHost = getDefaultEmulatorHost$1('auth');
|
|
25178
25645
|
if (authEmulatorHost) {
|
|
@@ -25180,6 +25647,31 @@ function getAuth(app = getApp()) {
|
|
|
25180
25647
|
}
|
|
25181
25648
|
return auth;
|
|
25182
25649
|
}
|
|
25650
|
+
function getScriptParentElement() {
|
|
25651
|
+
var _a, _b;
|
|
25652
|
+
return (_b = (_a = document.getElementsByTagName('head')) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : document;
|
|
25653
|
+
}
|
|
25654
|
+
_setExternalJSProvider({
|
|
25655
|
+
loadJS(url) {
|
|
25656
|
+
// TODO: consider adding timeout support & cancellation
|
|
25657
|
+
return new Promise((resolve, reject) => {
|
|
25658
|
+
const el = document.createElement('script');
|
|
25659
|
+
el.setAttribute('src', url);
|
|
25660
|
+
el.onload = resolve;
|
|
25661
|
+
el.onerror = e => {
|
|
25662
|
+
const error = _createError("internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
|
|
25663
|
+
error.customData = e;
|
|
25664
|
+
reject(error);
|
|
25665
|
+
};
|
|
25666
|
+
el.type = 'text/javascript';
|
|
25667
|
+
el.charset = 'UTF-8';
|
|
25668
|
+
getScriptParentElement().appendChild(el);
|
|
25669
|
+
});
|
|
25670
|
+
},
|
|
25671
|
+
gapiScript: 'https://apis.google.com/js/api.js',
|
|
25672
|
+
recaptchaV2Script: 'https://www.google.com/recaptcha/api.js',
|
|
25673
|
+
recaptchaEnterpriseScript: 'https://www.google.com/recaptcha/enterprise.js?render='
|
|
25674
|
+
});
|
|
25183
25675
|
registerAuth("Browser" /* ClientPlatform.BROWSER */);
|
|
25184
25676
|
|
|
25185
25677
|
const fromFirebaseDate = (date) => {
|
|
@@ -25218,16 +25710,16 @@ class FirebaseUser {
|
|
|
25218
25710
|
var _a;
|
|
25219
25711
|
return (_a = this.user) === null || _a === void 0 ? void 0 : _a.uid;
|
|
25220
25712
|
}
|
|
25221
|
-
onInit(brandId) {
|
|
25222
|
-
|
|
25223
|
-
|
|
25224
|
-
|
|
25225
|
-
|
|
25226
|
-
unsub();
|
|
25227
|
-
if (user)
|
|
25228
|
-
this.logUserLogin(brandId, user);
|
|
25229
|
-
});
|
|
25713
|
+
async onInit(brandId) {
|
|
25714
|
+
this.auth.onAuthStateChanged((user) => {
|
|
25715
|
+
this.setUser(user);
|
|
25716
|
+
if (user)
|
|
25717
|
+
this.logUserLogin(brandId, user);
|
|
25230
25718
|
});
|
|
25719
|
+
await this.auth.authStateReady();
|
|
25720
|
+
const user = this.auth.currentUser;
|
|
25721
|
+
this.setUser(user);
|
|
25722
|
+
return Boolean(user);
|
|
25231
25723
|
}
|
|
25232
25724
|
setUser(user) {
|
|
25233
25725
|
this.user = user;
|