@thefittingroom/sdk 1.5.0 → 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/api/responses.d.ts +1 -0
- package/dist/esm/index.js +982 -490
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.min.js +220 -190
- package/dist/esm/index.min.js.map +1 -1
- 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-03T15:43:56.403Z)
|
|
3
3
|
* Copyright 2022-present, TheFittingRoom, Inc. All rights reserved.
|
|
4
4
|
*/
|
|
5
5
|
// Code generated by tygo. DO NOT EDIT.
|
|
@@ -1947,8 +1947,8 @@ function isVersionServiceProvider(provider) {
|
|
|
1947
1947
|
return (component === null || component === void 0 ? void 0 : component.type) === "VERSION" /* ComponentType.VERSION */;
|
|
1948
1948
|
}
|
|
1949
1949
|
|
|
1950
|
-
const name$
|
|
1951
|
-
const version$1$1 = "0.9
|
|
1950
|
+
const name$p = "@firebase/app";
|
|
1951
|
+
const version$1$1 = "0.10.9";
|
|
1952
1952
|
|
|
1953
1953
|
/**
|
|
1954
1954
|
* @license
|
|
@@ -1968,54 +1968,56 @@ const version$1$1 = "0.9.13";
|
|
|
1968
1968
|
*/
|
|
1969
1969
|
const logger = new Logger$1('@firebase/app');
|
|
1970
1970
|
|
|
1971
|
-
const name$
|
|
1971
|
+
const name$o = "@firebase/app-compat";
|
|
1972
1972
|
|
|
1973
|
-
const name$
|
|
1973
|
+
const name$n = "@firebase/analytics-compat";
|
|
1974
1974
|
|
|
1975
|
-
const name$
|
|
1975
|
+
const name$m = "@firebase/analytics";
|
|
1976
1976
|
|
|
1977
|
-
const name$
|
|
1977
|
+
const name$l = "@firebase/app-check-compat";
|
|
1978
1978
|
|
|
1979
|
-
const name$
|
|
1979
|
+
const name$k = "@firebase/app-check";
|
|
1980
1980
|
|
|
1981
|
-
const name$
|
|
1981
|
+
const name$j = "@firebase/auth";
|
|
1982
1982
|
|
|
1983
|
-
const name$
|
|
1983
|
+
const name$i = "@firebase/auth-compat";
|
|
1984
1984
|
|
|
1985
|
-
const name$
|
|
1985
|
+
const name$h = "@firebase/database";
|
|
1986
1986
|
|
|
1987
|
-
const name$
|
|
1987
|
+
const name$g = "@firebase/database-compat";
|
|
1988
1988
|
|
|
1989
|
-
const name$
|
|
1989
|
+
const name$f = "@firebase/functions";
|
|
1990
1990
|
|
|
1991
|
-
const name$
|
|
1991
|
+
const name$e = "@firebase/functions-compat";
|
|
1992
1992
|
|
|
1993
|
-
const name$
|
|
1993
|
+
const name$d = "@firebase/installations";
|
|
1994
1994
|
|
|
1995
|
-
const name$
|
|
1995
|
+
const name$c = "@firebase/installations-compat";
|
|
1996
1996
|
|
|
1997
|
-
const name$
|
|
1997
|
+
const name$b = "@firebase/messaging";
|
|
1998
1998
|
|
|
1999
|
-
const name$
|
|
1999
|
+
const name$a = "@firebase/messaging-compat";
|
|
2000
2000
|
|
|
2001
|
-
const name$
|
|
2001
|
+
const name$9 = "@firebase/performance";
|
|
2002
2002
|
|
|
2003
|
-
const name$
|
|
2003
|
+
const name$8 = "@firebase/performance-compat";
|
|
2004
2004
|
|
|
2005
|
-
const name$
|
|
2005
|
+
const name$7 = "@firebase/remote-config";
|
|
2006
2006
|
|
|
2007
|
-
const name$
|
|
2007
|
+
const name$6 = "@firebase/remote-config-compat";
|
|
2008
2008
|
|
|
2009
|
-
const name$
|
|
2009
|
+
const name$5 = "@firebase/storage";
|
|
2010
2010
|
|
|
2011
|
-
const name$
|
|
2011
|
+
const name$4 = "@firebase/storage-compat";
|
|
2012
2012
|
|
|
2013
|
-
const name$
|
|
2013
|
+
const name$3 = "@firebase/firestore";
|
|
2014
|
+
|
|
2015
|
+
const name$2 = "@firebase/vertexai-preview";
|
|
2014
2016
|
|
|
2015
2017
|
const name$1$1 = "@firebase/firestore-compat";
|
|
2016
2018
|
|
|
2017
|
-
const name$
|
|
2018
|
-
const version$2 = "
|
|
2019
|
+
const name$q = "firebase";
|
|
2020
|
+
const version$2 = "10.13.0";
|
|
2019
2021
|
|
|
2020
2022
|
/**
|
|
2021
2023
|
* @license
|
|
@@ -2040,32 +2042,33 @@ const version$2 = "9.23.0";
|
|
|
2040
2042
|
*/
|
|
2041
2043
|
const DEFAULT_ENTRY_NAME = '[DEFAULT]';
|
|
2042
2044
|
const PLATFORM_LOG_STRING = {
|
|
2043
|
-
[name$
|
|
2044
|
-
[name$
|
|
2045
|
-
[name$
|
|
2046
|
-
[name$
|
|
2047
|
-
[name$
|
|
2048
|
-
[name$
|
|
2049
|
-
[name$
|
|
2050
|
-
[name$
|
|
2051
|
-
[name$
|
|
2052
|
-
[name$
|
|
2053
|
-
[name$
|
|
2054
|
-
[name$
|
|
2055
|
-
[name$
|
|
2056
|
-
[name$
|
|
2057
|
-
[name$
|
|
2058
|
-
[name$
|
|
2059
|
-
[name$
|
|
2060
|
-
[name$
|
|
2061
|
-
[name$
|
|
2062
|
-
[name$
|
|
2063
|
-
[name$
|
|
2064
|
-
[name$
|
|
2065
|
-
[name$
|
|
2045
|
+
[name$p]: 'fire-core',
|
|
2046
|
+
[name$o]: 'fire-core-compat',
|
|
2047
|
+
[name$m]: 'fire-analytics',
|
|
2048
|
+
[name$n]: 'fire-analytics-compat',
|
|
2049
|
+
[name$k]: 'fire-app-check',
|
|
2050
|
+
[name$l]: 'fire-app-check-compat',
|
|
2051
|
+
[name$j]: 'fire-auth',
|
|
2052
|
+
[name$i]: 'fire-auth-compat',
|
|
2053
|
+
[name$h]: 'fire-rtdb',
|
|
2054
|
+
[name$g]: 'fire-rtdb-compat',
|
|
2055
|
+
[name$f]: 'fire-fn',
|
|
2056
|
+
[name$e]: 'fire-fn-compat',
|
|
2057
|
+
[name$d]: 'fire-iid',
|
|
2058
|
+
[name$c]: 'fire-iid-compat',
|
|
2059
|
+
[name$b]: 'fire-fcm',
|
|
2060
|
+
[name$a]: 'fire-fcm-compat',
|
|
2061
|
+
[name$9]: 'fire-perf',
|
|
2062
|
+
[name$8]: 'fire-perf-compat',
|
|
2063
|
+
[name$7]: 'fire-rc',
|
|
2064
|
+
[name$6]: 'fire-rc-compat',
|
|
2065
|
+
[name$5]: 'fire-gcs',
|
|
2066
|
+
[name$4]: 'fire-gcs-compat',
|
|
2067
|
+
[name$3]: 'fire-fst',
|
|
2066
2068
|
[name$1$1]: 'fire-fst-compat',
|
|
2069
|
+
[name$2]: 'fire-vertex',
|
|
2067
2070
|
'fire-js': 'fire-js',
|
|
2068
|
-
[name$
|
|
2071
|
+
[name$q]: 'fire-js-all'
|
|
2069
2072
|
};
|
|
2070
2073
|
|
|
2071
2074
|
/**
|
|
@@ -2088,6 +2091,10 @@ const PLATFORM_LOG_STRING = {
|
|
|
2088
2091
|
* @internal
|
|
2089
2092
|
*/
|
|
2090
2093
|
const _apps = new Map();
|
|
2094
|
+
/**
|
|
2095
|
+
* @internal
|
|
2096
|
+
*/
|
|
2097
|
+
const _serverApps = new Map();
|
|
2091
2098
|
/**
|
|
2092
2099
|
* Registered components.
|
|
2093
2100
|
*
|
|
@@ -2126,6 +2133,9 @@ function _registerComponent(component) {
|
|
|
2126
2133
|
for (const app of _apps.values()) {
|
|
2127
2134
|
_addComponent(app, component);
|
|
2128
2135
|
}
|
|
2136
|
+
for (const serverApp of _serverApps.values()) {
|
|
2137
|
+
_addComponent(serverApp, component);
|
|
2138
|
+
}
|
|
2129
2139
|
return true;
|
|
2130
2140
|
}
|
|
2131
2141
|
/**
|
|
@@ -2146,6 +2156,17 @@ function _getProvider(app, name) {
|
|
|
2146
2156
|
}
|
|
2147
2157
|
return app.container.getProvider(name);
|
|
2148
2158
|
}
|
|
2159
|
+
/**
|
|
2160
|
+
*
|
|
2161
|
+
* @param obj - an object of type FirebaseApp.
|
|
2162
|
+
*
|
|
2163
|
+
* @returns true if the provided object is of type FirebaseServerAppImpl.
|
|
2164
|
+
*
|
|
2165
|
+
* @internal
|
|
2166
|
+
*/
|
|
2167
|
+
function _isFirebaseServerApp(obj) {
|
|
2168
|
+
return obj.settings !== undefined;
|
|
2169
|
+
}
|
|
2149
2170
|
|
|
2150
2171
|
/**
|
|
2151
2172
|
* @license
|
|
@@ -2166,9 +2187,10 @@ function _getProvider(app, name) {
|
|
|
2166
2187
|
const ERRORS = {
|
|
2167
2188
|
["no-app" /* AppError.NO_APP */]: "No Firebase App '{$appName}' has been created - " +
|
|
2168
2189
|
'call initializeApp() first',
|
|
2169
|
-
["bad-app-name" /* AppError.BAD_APP_NAME */]: "Illegal App name: '{$appName}",
|
|
2190
|
+
["bad-app-name" /* AppError.BAD_APP_NAME */]: "Illegal App name: '{$appName}'",
|
|
2170
2191
|
["duplicate-app" /* AppError.DUPLICATE_APP */]: "Firebase App named '{$appName}' already exists with different options or config",
|
|
2171
2192
|
["app-deleted" /* AppError.APP_DELETED */]: "Firebase App named '{$appName}' already deleted",
|
|
2193
|
+
["server-app-deleted" /* AppError.SERVER_APP_DELETED */]: 'Firebase Server App has been deleted',
|
|
2172
2194
|
["no-options" /* AppError.NO_OPTIONS */]: 'Need to provide options, when not being deployed to hosting via source.',
|
|
2173
2195
|
["invalid-app-argument" /* AppError.INVALID_APP_ARGUMENT */]: 'firebase.{$appName}() takes either no argument or a ' +
|
|
2174
2196
|
'Firebase App instance.',
|
|
@@ -2176,7 +2198,9 @@ const ERRORS = {
|
|
|
2176
2198
|
["idb-open" /* AppError.IDB_OPEN */]: 'Error thrown when opening IndexedDB. Original error: {$originalErrorMessage}.',
|
|
2177
2199
|
["idb-get" /* AppError.IDB_GET */]: 'Error thrown when reading from IndexedDB. Original error: {$originalErrorMessage}.',
|
|
2178
2200
|
["idb-set" /* AppError.IDB_WRITE */]: 'Error thrown when writing to IndexedDB. Original error: {$originalErrorMessage}.',
|
|
2179
|
-
["idb-delete" /* AppError.IDB_DELETE */]: 'Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}.'
|
|
2201
|
+
["idb-delete" /* AppError.IDB_DELETE */]: 'Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}.',
|
|
2202
|
+
["finalization-registry-not-supported" /* AppError.FINALIZATION_REGISTRY_NOT_SUPPORTED */]: 'FirebaseServerApp deleteOnDeref field defined but the JS runtime does not support FinalizationRegistry.',
|
|
2203
|
+
["invalid-server-app-environment" /* AppError.INVALID_SERVER_APP_ENVIRONMENT */]: 'FirebaseServerApp is not for use in browser environments.'
|
|
2180
2204
|
};
|
|
2181
2205
|
const ERROR_FACTORY = new ErrorFactory$1('app', 'Firebase', ERRORS);
|
|
2182
2206
|
|
|
@@ -2412,7 +2436,15 @@ function getDbPromise() {
|
|
|
2412
2436
|
// eslint-disable-next-line default-case
|
|
2413
2437
|
switch (oldVersion) {
|
|
2414
2438
|
case 0:
|
|
2415
|
-
|
|
2439
|
+
try {
|
|
2440
|
+
db.createObjectStore(STORE_NAME);
|
|
2441
|
+
}
|
|
2442
|
+
catch (e) {
|
|
2443
|
+
// Safari/iOS browsers throw occasional exceptions on
|
|
2444
|
+
// db.createObjectStore() that may be a bug. Avoid blocking
|
|
2445
|
+
// the rest of the app functionality.
|
|
2446
|
+
console.warn(e);
|
|
2447
|
+
}
|
|
2416
2448
|
}
|
|
2417
2449
|
}
|
|
2418
2450
|
}).catch(e => {
|
|
@@ -2426,10 +2458,11 @@ function getDbPromise() {
|
|
|
2426
2458
|
async function readHeartbeatsFromIndexedDB(app) {
|
|
2427
2459
|
try {
|
|
2428
2460
|
const db = await getDbPromise();
|
|
2429
|
-
const
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2461
|
+
const tx = db.transaction(STORE_NAME);
|
|
2462
|
+
const result = await tx.objectStore(STORE_NAME).get(computeKey(app));
|
|
2463
|
+
// We already have the value but tx.done can throw,
|
|
2464
|
+
// so we need to await it here to catch errors
|
|
2465
|
+
await tx.done;
|
|
2433
2466
|
return result;
|
|
2434
2467
|
}
|
|
2435
2468
|
catch (e) {
|
|
@@ -2515,33 +2548,45 @@ class HeartbeatServiceImpl {
|
|
|
2515
2548
|
* already logged, subsequent calls to this function in the same day will be ignored.
|
|
2516
2549
|
*/
|
|
2517
2550
|
async triggerHeartbeat() {
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
.
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2551
|
+
var _a, _b, _c;
|
|
2552
|
+
try {
|
|
2553
|
+
const platformLogger = this.container
|
|
2554
|
+
.getProvider('platform-logger')
|
|
2555
|
+
.getImmediate();
|
|
2556
|
+
// This is the "Firebase user agent" string from the platform logger
|
|
2557
|
+
// service, not the browser user agent.
|
|
2558
|
+
const agent = platformLogger.getPlatformInfoString();
|
|
2559
|
+
const date = getUTCDateString();
|
|
2560
|
+
console.log('heartbeats', (_a = this._heartbeatsCache) === null || _a === void 0 ? void 0 : _a.heartbeats);
|
|
2561
|
+
if (((_b = this._heartbeatsCache) === null || _b === void 0 ? void 0 : _b.heartbeats) == null) {
|
|
2562
|
+
this._heartbeatsCache = await this._heartbeatsCachePromise;
|
|
2563
|
+
// If we failed to construct a heartbeats cache, then return immediately.
|
|
2564
|
+
if (((_c = this._heartbeatsCache) === null || _c === void 0 ? void 0 : _c.heartbeats) == null) {
|
|
2565
|
+
return;
|
|
2566
|
+
}
|
|
2567
|
+
}
|
|
2568
|
+
// Do not store a heartbeat if one is already stored for this day
|
|
2569
|
+
// or if a header has already been sent today.
|
|
2570
|
+
if (this._heartbeatsCache.lastSentHeartbeatDate === date ||
|
|
2571
|
+
this._heartbeatsCache.heartbeats.some(singleDateHeartbeat => singleDateHeartbeat.date === date)) {
|
|
2572
|
+
return;
|
|
2573
|
+
}
|
|
2574
|
+
else {
|
|
2575
|
+
// There is no entry for this date. Create one.
|
|
2576
|
+
this._heartbeatsCache.heartbeats.push({ date, agent });
|
|
2577
|
+
}
|
|
2578
|
+
// Remove entries older than 30 days.
|
|
2579
|
+
this._heartbeatsCache.heartbeats =
|
|
2580
|
+
this._heartbeatsCache.heartbeats.filter(singleDateHeartbeat => {
|
|
2581
|
+
const hbTimestamp = new Date(singleDateHeartbeat.date).valueOf();
|
|
2582
|
+
const now = Date.now();
|
|
2583
|
+
return now - hbTimestamp <= STORED_HEARTBEAT_RETENTION_MAX_MILLIS;
|
|
2584
|
+
});
|
|
2585
|
+
return this._storage.overwrite(this._heartbeatsCache);
|
|
2586
|
+
}
|
|
2587
|
+
catch (e) {
|
|
2588
|
+
logger.warn(e);
|
|
2533
2589
|
}
|
|
2534
|
-
else {
|
|
2535
|
-
// There is no entry for this date. Create one.
|
|
2536
|
-
this._heartbeatsCache.heartbeats.push({ date, agent });
|
|
2537
|
-
}
|
|
2538
|
-
// Remove entries older than 30 days.
|
|
2539
|
-
this._heartbeatsCache.heartbeats = this._heartbeatsCache.heartbeats.filter(singleDateHeartbeat => {
|
|
2540
|
-
const hbTimestamp = new Date(singleDateHeartbeat.date).valueOf();
|
|
2541
|
-
const now = Date.now();
|
|
2542
|
-
return now - hbTimestamp <= STORED_HEARTBEAT_RETENTION_MAX_MILLIS;
|
|
2543
|
-
});
|
|
2544
|
-
return this._storage.overwrite(this._heartbeatsCache);
|
|
2545
2590
|
}
|
|
2546
2591
|
/**
|
|
2547
2592
|
* Returns a base64 encoded string which can be attached to the heartbeat-specific header directly.
|
|
@@ -2551,34 +2596,41 @@ class HeartbeatServiceImpl {
|
|
|
2551
2596
|
* returns an empty string.
|
|
2552
2597
|
*/
|
|
2553
2598
|
async getHeartbeatsHeader() {
|
|
2554
|
-
|
|
2555
|
-
|
|
2599
|
+
var _a;
|
|
2600
|
+
try {
|
|
2601
|
+
if (this._heartbeatsCache === null) {
|
|
2602
|
+
await this._heartbeatsCachePromise;
|
|
2603
|
+
}
|
|
2604
|
+
// If it's still null or the array is empty, there is no data to send.
|
|
2605
|
+
if (((_a = this._heartbeatsCache) === null || _a === void 0 ? void 0 : _a.heartbeats) == null ||
|
|
2606
|
+
this._heartbeatsCache.heartbeats.length === 0) {
|
|
2607
|
+
return '';
|
|
2608
|
+
}
|
|
2609
|
+
const date = getUTCDateString();
|
|
2610
|
+
// Extract as many heartbeats from the cache as will fit under the size limit.
|
|
2611
|
+
const { heartbeatsToSend, unsentEntries } = extractHeartbeatsForHeader(this._heartbeatsCache.heartbeats);
|
|
2612
|
+
const headerString = base64urlEncodeWithoutPadding$1(JSON.stringify({ version: 2, heartbeats: heartbeatsToSend }));
|
|
2613
|
+
// Store last sent date to prevent another being logged/sent for the same day.
|
|
2614
|
+
this._heartbeatsCache.lastSentHeartbeatDate = date;
|
|
2615
|
+
if (unsentEntries.length > 0) {
|
|
2616
|
+
// Store any unsent entries if they exist.
|
|
2617
|
+
this._heartbeatsCache.heartbeats = unsentEntries;
|
|
2618
|
+
// This seems more likely than emptying the array (below) to lead to some odd state
|
|
2619
|
+
// since the cache isn't empty and this will be called again on the next request,
|
|
2620
|
+
// and is probably safest if we await it.
|
|
2621
|
+
await this._storage.overwrite(this._heartbeatsCache);
|
|
2622
|
+
}
|
|
2623
|
+
else {
|
|
2624
|
+
this._heartbeatsCache.heartbeats = [];
|
|
2625
|
+
// Do not wait for this, to reduce latency.
|
|
2626
|
+
void this._storage.overwrite(this._heartbeatsCache);
|
|
2627
|
+
}
|
|
2628
|
+
return headerString;
|
|
2556
2629
|
}
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
this._heartbeatsCache.heartbeats.length === 0) {
|
|
2630
|
+
catch (e) {
|
|
2631
|
+
logger.warn(e);
|
|
2560
2632
|
return '';
|
|
2561
2633
|
}
|
|
2562
|
-
const date = getUTCDateString();
|
|
2563
|
-
// Extract as many heartbeats from the cache as will fit under the size limit.
|
|
2564
|
-
const { heartbeatsToSend, unsentEntries } = extractHeartbeatsForHeader(this._heartbeatsCache.heartbeats);
|
|
2565
|
-
const headerString = base64urlEncodeWithoutPadding$1(JSON.stringify({ version: 2, heartbeats: heartbeatsToSend }));
|
|
2566
|
-
// Store last sent date to prevent another being logged/sent for the same day.
|
|
2567
|
-
this._heartbeatsCache.lastSentHeartbeatDate = date;
|
|
2568
|
-
if (unsentEntries.length > 0) {
|
|
2569
|
-
// Store any unsent entries if they exist.
|
|
2570
|
-
this._heartbeatsCache.heartbeats = unsentEntries;
|
|
2571
|
-
// This seems more likely than emptying the array (below) to lead to some odd state
|
|
2572
|
-
// since the cache isn't empty and this will be called again on the next request,
|
|
2573
|
-
// and is probably safest if we await it.
|
|
2574
|
-
await this._storage.overwrite(this._heartbeatsCache);
|
|
2575
|
-
}
|
|
2576
|
-
else {
|
|
2577
|
-
this._heartbeatsCache.heartbeats = [];
|
|
2578
|
-
// Do not wait for this, to reduce latency.
|
|
2579
|
-
void this._storage.overwrite(this._heartbeatsCache);
|
|
2580
|
-
}
|
|
2581
|
-
return headerString;
|
|
2582
2634
|
}
|
|
2583
2635
|
}
|
|
2584
2636
|
function getUTCDateString() {
|
|
@@ -2651,7 +2703,12 @@ class HeartbeatStorageImpl {
|
|
|
2651
2703
|
}
|
|
2652
2704
|
else {
|
|
2653
2705
|
const idbHeartbeatObject = await readHeartbeatsFromIndexedDB(this.app);
|
|
2654
|
-
|
|
2706
|
+
if (idbHeartbeatObject === null || idbHeartbeatObject === void 0 ? void 0 : idbHeartbeatObject.heartbeats) {
|
|
2707
|
+
return idbHeartbeatObject;
|
|
2708
|
+
}
|
|
2709
|
+
else {
|
|
2710
|
+
return { heartbeats: [] };
|
|
2711
|
+
}
|
|
2655
2712
|
}
|
|
2656
2713
|
}
|
|
2657
2714
|
// overwrite the storage with the provided heartbeats
|
|
@@ -2720,9 +2777,9 @@ function registerCoreComponents(variant) {
|
|
|
2720
2777
|
_registerComponent(new Component$1('platform-logger', container => new PlatformLoggerServiceImpl(container), "PRIVATE" /* ComponentType.PRIVATE */));
|
|
2721
2778
|
_registerComponent(new Component$1('heartbeat', container => new HeartbeatServiceImpl(container), "PRIVATE" /* ComponentType.PRIVATE */));
|
|
2722
2779
|
// Register `app` package.
|
|
2723
|
-
registerVersion(name$
|
|
2780
|
+
registerVersion(name$p, version$1$1, variant);
|
|
2724
2781
|
// BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
|
|
2725
|
-
registerVersion(name$
|
|
2782
|
+
registerVersion(name$p, version$1$1, 'esm2017');
|
|
2726
2783
|
// Register platform SDK identifier (no version).
|
|
2727
2784
|
registerVersion('fire-js', '');
|
|
2728
2785
|
}
|
|
@@ -17789,7 +17846,7 @@ function jl(t, ...e) {
|
|
|
17789
17846
|
}();
|
|
17790
17847
|
|
|
17791
17848
|
var name$1 = "firebase";
|
|
17792
|
-
var version$1 = "
|
|
17849
|
+
var version$1 = "10.13.0";
|
|
17793
17850
|
|
|
17794
17851
|
/**
|
|
17795
17852
|
* @license
|
|
@@ -18605,6 +18662,7 @@ const AUTH_ERROR_CODES_MAP_DO_NOT_USE_INTERNALLY = {
|
|
|
18605
18662
|
INVALID_EMAIL: 'auth/invalid-email',
|
|
18606
18663
|
INVALID_EMULATOR_SCHEME: 'auth/invalid-emulator-scheme',
|
|
18607
18664
|
INVALID_IDP_RESPONSE: 'auth/invalid-credential',
|
|
18665
|
+
INVALID_LOGIN_CREDENTIALS: 'auth/invalid-credential',
|
|
18608
18666
|
INVALID_MESSAGE_PAYLOAD: 'auth/invalid-message-payload',
|
|
18609
18667
|
INVALID_MFA_SESSION: 'auth/invalid-multi-factor-session',
|
|
18610
18668
|
INVALID_OAUTH_CLIENT_ID: 'auth/invalid-oauth-client-id',
|
|
@@ -18734,6 +18792,9 @@ function _errorWithCustomMessage(auth, code, message) {
|
|
|
18734
18792
|
appName: auth.name
|
|
18735
18793
|
});
|
|
18736
18794
|
}
|
|
18795
|
+
function _serverAppCurrentUserOperationNotSupportedError(auth) {
|
|
18796
|
+
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');
|
|
18797
|
+
}
|
|
18737
18798
|
function createErrorInternal(authOrCode, ...rest) {
|
|
18738
18799
|
if (typeof authOrCode !== 'string') {
|
|
18739
18800
|
const code = rest[0];
|
|
@@ -18957,6 +19018,12 @@ class FetchProvider {
|
|
|
18957
19018
|
if (typeof self !== 'undefined' && 'fetch' in self) {
|
|
18958
19019
|
return self.fetch;
|
|
18959
19020
|
}
|
|
19021
|
+
if (typeof globalThis !== 'undefined' && globalThis.fetch) {
|
|
19022
|
+
return globalThis.fetch;
|
|
19023
|
+
}
|
|
19024
|
+
if (typeof fetch !== 'undefined') {
|
|
19025
|
+
return fetch;
|
|
19026
|
+
}
|
|
18960
19027
|
debugFail('Could not find fetch implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill');
|
|
18961
19028
|
}
|
|
18962
19029
|
static headers() {
|
|
@@ -18966,6 +19033,12 @@ class FetchProvider {
|
|
|
18966
19033
|
if (typeof self !== 'undefined' && 'Headers' in self) {
|
|
18967
19034
|
return self.Headers;
|
|
18968
19035
|
}
|
|
19036
|
+
if (typeof globalThis !== 'undefined' && globalThis.Headers) {
|
|
19037
|
+
return globalThis.Headers;
|
|
19038
|
+
}
|
|
19039
|
+
if (typeof Headers !== 'undefined') {
|
|
19040
|
+
return Headers;
|
|
19041
|
+
}
|
|
18969
19042
|
debugFail('Could not find Headers implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill');
|
|
18970
19043
|
}
|
|
18971
19044
|
static response() {
|
|
@@ -18975,6 +19048,12 @@ class FetchProvider {
|
|
|
18975
19048
|
if (typeof self !== 'undefined' && 'Response' in self) {
|
|
18976
19049
|
return self.Response;
|
|
18977
19050
|
}
|
|
19051
|
+
if (typeof globalThis !== 'undefined' && globalThis.Response) {
|
|
19052
|
+
return globalThis.Response;
|
|
19053
|
+
}
|
|
19054
|
+
if (typeof Response !== 'undefined') {
|
|
19055
|
+
return Response;
|
|
19056
|
+
}
|
|
18978
19057
|
debugFail('Could not find Response implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill');
|
|
18979
19058
|
}
|
|
18980
19059
|
}
|
|
@@ -19011,12 +19090,15 @@ const SERVER_ERROR_MAP = {
|
|
|
19011
19090
|
["INVALID_PASSWORD" /* ServerError.INVALID_PASSWORD */]: "wrong-password" /* AuthErrorCode.INVALID_PASSWORD */,
|
|
19012
19091
|
// This can only happen if the SDK sends a bad request.
|
|
19013
19092
|
["MISSING_PASSWORD" /* ServerError.MISSING_PASSWORD */]: "missing-password" /* AuthErrorCode.MISSING_PASSWORD */,
|
|
19093
|
+
// Thrown if Email Enumeration Protection is enabled in the project and the email or password is
|
|
19094
|
+
// invalid.
|
|
19095
|
+
["INVALID_LOGIN_CREDENTIALS" /* ServerError.INVALID_LOGIN_CREDENTIALS */]: "invalid-credential" /* AuthErrorCode.INVALID_CREDENTIAL */,
|
|
19014
19096
|
// Sign up with email and password errors.
|
|
19015
19097
|
["EMAIL_EXISTS" /* ServerError.EMAIL_EXISTS */]: "email-already-in-use" /* AuthErrorCode.EMAIL_EXISTS */,
|
|
19016
19098
|
["PASSWORD_LOGIN_DISABLED" /* ServerError.PASSWORD_LOGIN_DISABLED */]: "operation-not-allowed" /* AuthErrorCode.OPERATION_NOT_ALLOWED */,
|
|
19017
19099
|
// Verify assertion for sign in with credential errors:
|
|
19018
|
-
["INVALID_IDP_RESPONSE" /* ServerError.INVALID_IDP_RESPONSE */]: "invalid-credential" /* AuthErrorCode.
|
|
19019
|
-
["INVALID_PENDING_TOKEN" /* ServerError.INVALID_PENDING_TOKEN */]: "invalid-credential" /* AuthErrorCode.
|
|
19100
|
+
["INVALID_IDP_RESPONSE" /* ServerError.INVALID_IDP_RESPONSE */]: "invalid-credential" /* AuthErrorCode.INVALID_CREDENTIAL */,
|
|
19101
|
+
["INVALID_PENDING_TOKEN" /* ServerError.INVALID_PENDING_TOKEN */]: "invalid-credential" /* AuthErrorCode.INVALID_CREDENTIAL */,
|
|
19020
19102
|
["FEDERATED_USER_ID_ALREADY_LINKED" /* ServerError.FEDERATED_USER_ID_ALREADY_LINKED */]: "credential-already-in-use" /* AuthErrorCode.CREDENTIAL_ALREADY_IN_USE */,
|
|
19021
19103
|
// This can only happen if the SDK sends a bad request.
|
|
19022
19104
|
["MISSING_REQ_TYPE" /* ServerError.MISSING_REQ_TYPE */]: "internal-error" /* AuthErrorCode.INTERNAL_ERROR */,
|
|
@@ -19034,10 +19116,11 @@ const SERVER_ERROR_MAP = {
|
|
|
19034
19116
|
["USER_NOT_FOUND" /* ServerError.USER_NOT_FOUND */]: "user-token-expired" /* AuthErrorCode.TOKEN_EXPIRED */,
|
|
19035
19117
|
// Other errors.
|
|
19036
19118
|
["TOO_MANY_ATTEMPTS_TRY_LATER" /* ServerError.TOO_MANY_ATTEMPTS_TRY_LATER */]: "too-many-requests" /* AuthErrorCode.TOO_MANY_ATTEMPTS_TRY_LATER */,
|
|
19119
|
+
["PASSWORD_DOES_NOT_MEET_REQUIREMENTS" /* ServerError.PASSWORD_DOES_NOT_MEET_REQUIREMENTS */]: "password-does-not-meet-requirements" /* AuthErrorCode.PASSWORD_DOES_NOT_MEET_REQUIREMENTS */,
|
|
19037
19120
|
// Phone Auth related errors.
|
|
19038
19121
|
["INVALID_CODE" /* ServerError.INVALID_CODE */]: "invalid-verification-code" /* AuthErrorCode.INVALID_CODE */,
|
|
19039
19122
|
["INVALID_SESSION_INFO" /* ServerError.INVALID_SESSION_INFO */]: "invalid-verification-id" /* AuthErrorCode.INVALID_SESSION_INFO */,
|
|
19040
|
-
["INVALID_TEMPORARY_PROOF" /* ServerError.INVALID_TEMPORARY_PROOF */]: "invalid-credential" /* AuthErrorCode.
|
|
19123
|
+
["INVALID_TEMPORARY_PROOF" /* ServerError.INVALID_TEMPORARY_PROOF */]: "invalid-credential" /* AuthErrorCode.INVALID_CREDENTIAL */,
|
|
19041
19124
|
["MISSING_SESSION_INFO" /* ServerError.MISSING_SESSION_INFO */]: "missing-verification-id" /* AuthErrorCode.MISSING_SESSION_INFO */,
|
|
19042
19125
|
["SESSION_EXPIRED" /* ServerError.SESSION_EXPIRED */]: "code-expired" /* AuthErrorCode.CODE_EXPIRED */,
|
|
19043
19126
|
// Other action code errors when additional settings passed.
|
|
@@ -19185,6 +19268,18 @@ function _getFinalTarget(auth, host, path, query) {
|
|
|
19185
19268
|
}
|
|
19186
19269
|
return _emulatorUrl(auth.config, base);
|
|
19187
19270
|
}
|
|
19271
|
+
function _parseEnforcementState(enforcementStateStr) {
|
|
19272
|
+
switch (enforcementStateStr) {
|
|
19273
|
+
case 'ENFORCE':
|
|
19274
|
+
return "ENFORCE" /* EnforcementState.ENFORCE */;
|
|
19275
|
+
case 'AUDIT':
|
|
19276
|
+
return "AUDIT" /* EnforcementState.AUDIT */;
|
|
19277
|
+
case 'OFF':
|
|
19278
|
+
return "OFF" /* EnforcementState.OFF */;
|
|
19279
|
+
default:
|
|
19280
|
+
return "ENFORCEMENT_STATE_UNSPECIFIED" /* EnforcementState.ENFORCEMENT_STATE_UNSPECIFIED */;
|
|
19281
|
+
}
|
|
19282
|
+
}
|
|
19188
19283
|
class NetworkTimeout {
|
|
19189
19284
|
constructor(auth) {
|
|
19190
19285
|
this.auth = auth;
|
|
@@ -19217,6 +19312,61 @@ function _makeTaggedError(auth, code, response) {
|
|
|
19217
19312
|
error.customData._tokenResponse = response;
|
|
19218
19313
|
return error;
|
|
19219
19314
|
}
|
|
19315
|
+
function isEnterprise(grecaptcha) {
|
|
19316
|
+
return (grecaptcha !== undefined &&
|
|
19317
|
+
grecaptcha.enterprise !== undefined);
|
|
19318
|
+
}
|
|
19319
|
+
class RecaptchaConfig {
|
|
19320
|
+
constructor(response) {
|
|
19321
|
+
/**
|
|
19322
|
+
* The reCAPTCHA site key.
|
|
19323
|
+
*/
|
|
19324
|
+
this.siteKey = '';
|
|
19325
|
+
/**
|
|
19326
|
+
* The list of providers and their enablement status for reCAPTCHA Enterprise.
|
|
19327
|
+
*/
|
|
19328
|
+
this.recaptchaEnforcementState = [];
|
|
19329
|
+
if (response.recaptchaKey === undefined) {
|
|
19330
|
+
throw new Error('recaptchaKey undefined');
|
|
19331
|
+
}
|
|
19332
|
+
// Example response.recaptchaKey: "projects/proj123/keys/sitekey123"
|
|
19333
|
+
this.siteKey = response.recaptchaKey.split('/')[3];
|
|
19334
|
+
this.recaptchaEnforcementState = response.recaptchaEnforcementState;
|
|
19335
|
+
}
|
|
19336
|
+
/**
|
|
19337
|
+
* Returns the reCAPTCHA Enterprise enforcement state for the given provider.
|
|
19338
|
+
*
|
|
19339
|
+
* @param providerStr - The provider whose enforcement state is to be returned.
|
|
19340
|
+
* @returns The reCAPTCHA Enterprise enforcement state for the given provider.
|
|
19341
|
+
*/
|
|
19342
|
+
getProviderEnforcementState(providerStr) {
|
|
19343
|
+
if (!this.recaptchaEnforcementState ||
|
|
19344
|
+
this.recaptchaEnforcementState.length === 0) {
|
|
19345
|
+
return null;
|
|
19346
|
+
}
|
|
19347
|
+
for (const recaptchaEnforcementState of this.recaptchaEnforcementState) {
|
|
19348
|
+
if (recaptchaEnforcementState.provider &&
|
|
19349
|
+
recaptchaEnforcementState.provider === providerStr) {
|
|
19350
|
+
return _parseEnforcementState(recaptchaEnforcementState.enforcementState);
|
|
19351
|
+
}
|
|
19352
|
+
}
|
|
19353
|
+
return null;
|
|
19354
|
+
}
|
|
19355
|
+
/**
|
|
19356
|
+
* Returns true if the reCAPTCHA Enterprise enforcement state for the provider is set to ENFORCE or AUDIT.
|
|
19357
|
+
*
|
|
19358
|
+
* @param providerStr - The provider whose enablement state is to be returned.
|
|
19359
|
+
* @returns Whether or not reCAPTCHA Enterprise protection is enabled for the given provider.
|
|
19360
|
+
*/
|
|
19361
|
+
isProviderEnabled(providerStr) {
|
|
19362
|
+
return (this.getProviderEnforcementState(providerStr) ===
|
|
19363
|
+
"ENFORCE" /* EnforcementState.ENFORCE */ ||
|
|
19364
|
+
this.getProviderEnforcementState(providerStr) === "AUDIT" /* EnforcementState.AUDIT */);
|
|
19365
|
+
}
|
|
19366
|
+
}
|
|
19367
|
+
async function getRecaptchaConfig(auth, request) {
|
|
19368
|
+
return _performApiRequest(auth, "GET" /* HttpMethod.GET */, "/v2/recaptchaConfig" /* Endpoint.GET_RECAPTCHA_CONFIG */, _addTidIfNecessary(auth, request));
|
|
19369
|
+
}
|
|
19220
19370
|
|
|
19221
19371
|
/**
|
|
19222
19372
|
* @license
|
|
@@ -19621,6 +19771,9 @@ async function requestStsToken(auth, refreshToken) {
|
|
|
19621
19771
|
expiresIn: response.expires_in,
|
|
19622
19772
|
refreshToken: response.refresh_token
|
|
19623
19773
|
};
|
|
19774
|
+
}
|
|
19775
|
+
async function revokeToken(auth, request) {
|
|
19776
|
+
return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v2/accounts:revokeToken" /* Endpoint.REVOKE_TOKEN */, _addTidIfNecessary(auth, request));
|
|
19624
19777
|
}
|
|
19625
19778
|
|
|
19626
19779
|
/**
|
|
@@ -19664,11 +19817,16 @@ class StsTokenManager {
|
|
|
19664
19817
|
: _tokenExpiresIn(response.idToken);
|
|
19665
19818
|
this.updateTokensAndExpiration(response.idToken, response.refreshToken, expiresIn);
|
|
19666
19819
|
}
|
|
19820
|
+
updateFromIdToken(idToken) {
|
|
19821
|
+
_assert(idToken.length !== 0, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
|
|
19822
|
+
const expiresIn = _tokenExpiresIn(idToken);
|
|
19823
|
+
this.updateTokensAndExpiration(idToken, null, expiresIn);
|
|
19824
|
+
}
|
|
19667
19825
|
async getToken(auth, forceRefresh = false) {
|
|
19668
|
-
_assert(!this.accessToken || this.refreshToken, auth, "user-token-expired" /* AuthErrorCode.TOKEN_EXPIRED */);
|
|
19669
19826
|
if (!forceRefresh && this.accessToken && !this.isExpired) {
|
|
19670
19827
|
return this.accessToken;
|
|
19671
19828
|
}
|
|
19829
|
+
_assert(this.refreshToken, auth, "user-token-expired" /* AuthErrorCode.TOKEN_EXPIRED */);
|
|
19672
19830
|
if (this.refreshToken) {
|
|
19673
19831
|
await this.refresh(auth, this.refreshToken);
|
|
19674
19832
|
return this.accessToken;
|
|
@@ -19848,6 +20006,9 @@ class UserImpl {
|
|
|
19848
20006
|
}
|
|
19849
20007
|
}
|
|
19850
20008
|
async delete() {
|
|
20009
|
+
if (_isFirebaseServerApp(this.auth.app)) {
|
|
20010
|
+
return Promise.reject(_serverAppCurrentUserOperationNotSupportedError(this.auth));
|
|
20011
|
+
}
|
|
19851
20012
|
const idToken = await this.getIdToken();
|
|
19852
20013
|
await _logoutIfInvalidated(this, deleteAccount(this.auth, { idToken }));
|
|
19853
20014
|
this.stsTokenManager.clearRefreshToken();
|
|
@@ -19931,6 +20092,44 @@ class UserImpl {
|
|
|
19931
20092
|
await _reloadWithoutSaving(user);
|
|
19932
20093
|
return user;
|
|
19933
20094
|
}
|
|
20095
|
+
/**
|
|
20096
|
+
* Initialize a User from an idToken server response
|
|
20097
|
+
* @param auth
|
|
20098
|
+
* @param idTokenResponse
|
|
20099
|
+
*/
|
|
20100
|
+
static async _fromGetAccountInfoResponse(auth, response, idToken) {
|
|
20101
|
+
const coreAccount = response.users[0];
|
|
20102
|
+
_assert(coreAccount.localId !== undefined, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
|
|
20103
|
+
const providerData = coreAccount.providerUserInfo !== undefined
|
|
20104
|
+
? extractProviderData(coreAccount.providerUserInfo)
|
|
20105
|
+
: [];
|
|
20106
|
+
const isAnonymous = !(coreAccount.email && coreAccount.passwordHash) && !(providerData === null || providerData === void 0 ? void 0 : providerData.length);
|
|
20107
|
+
const stsTokenManager = new StsTokenManager();
|
|
20108
|
+
stsTokenManager.updateFromIdToken(idToken);
|
|
20109
|
+
// Initialize the Firebase Auth user.
|
|
20110
|
+
const user = new UserImpl({
|
|
20111
|
+
uid: coreAccount.localId,
|
|
20112
|
+
auth,
|
|
20113
|
+
stsTokenManager,
|
|
20114
|
+
isAnonymous
|
|
20115
|
+
});
|
|
20116
|
+
// update the user with data from the GetAccountInfo response.
|
|
20117
|
+
const updates = {
|
|
20118
|
+
uid: coreAccount.localId,
|
|
20119
|
+
displayName: coreAccount.displayName || null,
|
|
20120
|
+
photoURL: coreAccount.photoUrl || null,
|
|
20121
|
+
email: coreAccount.email || null,
|
|
20122
|
+
emailVerified: coreAccount.emailVerified || false,
|
|
20123
|
+
phoneNumber: coreAccount.phoneNumber || null,
|
|
20124
|
+
tenantId: coreAccount.tenantId || null,
|
|
20125
|
+
providerData,
|
|
20126
|
+
metadata: new UserMetadata(coreAccount.createdAt, coreAccount.lastLoginAt),
|
|
20127
|
+
isAnonymous: !(coreAccount.email && coreAccount.passwordHash) &&
|
|
20128
|
+
!(providerData === null || providerData === void 0 ? void 0 : providerData.length)
|
|
20129
|
+
};
|
|
20130
|
+
Object.assign(user, updates);
|
|
20131
|
+
return user;
|
|
20132
|
+
}
|
|
19934
20133
|
}
|
|
19935
20134
|
|
|
19936
20135
|
/**
|
|
@@ -20246,16 +20445,6 @@ function _isMobileBrowser(ua = getUA()) {
|
|
|
20246
20445
|
_isBlackBerry(ua) ||
|
|
20247
20446
|
/windows phone/i.test(ua) ||
|
|
20248
20447
|
_isIEMobile(ua));
|
|
20249
|
-
}
|
|
20250
|
-
function _isIframe() {
|
|
20251
|
-
try {
|
|
20252
|
-
// Check that the current window is not the top window.
|
|
20253
|
-
// If so, return true.
|
|
20254
|
-
return !!(window && window !== window.top);
|
|
20255
|
-
}
|
|
20256
|
-
catch (e) {
|
|
20257
|
-
return false;
|
|
20258
|
-
}
|
|
20259
20448
|
}
|
|
20260
20449
|
|
|
20261
20450
|
/**
|
|
@@ -20298,36 +20487,91 @@ function _getClientVersion(clientPlatform, frameworks = []) {
|
|
|
20298
20487
|
: 'FirebaseCore-web'; /* default value if no other framework is used */
|
|
20299
20488
|
return `${reportedPlatform}/${"JsCore" /* ClientImplementation.CORE */}/${SDK_VERSION}/${reportedFrameworks}`;
|
|
20300
20489
|
}
|
|
20301
|
-
|
|
20302
|
-
|
|
20303
|
-
|
|
20304
|
-
|
|
20305
|
-
|
|
20306
|
-
|
|
20307
|
-
|
|
20308
|
-
|
|
20309
|
-
|
|
20310
|
-
|
|
20311
|
-
|
|
20312
|
-
|
|
20313
|
-
|
|
20314
|
-
|
|
20315
|
-
|
|
20316
|
-
|
|
20317
|
-
|
|
20318
|
-
|
|
20319
|
-
|
|
20490
|
+
|
|
20491
|
+
/**
|
|
20492
|
+
* @license
|
|
20493
|
+
* Copyright 2022 Google LLC
|
|
20494
|
+
*
|
|
20495
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
20496
|
+
* you may not use this file except in compliance with the License.
|
|
20497
|
+
* You may obtain a copy of the License at
|
|
20498
|
+
*
|
|
20499
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
20500
|
+
*
|
|
20501
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
20502
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
20503
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
20504
|
+
* See the License for the specific language governing permissions and
|
|
20505
|
+
* limitations under the License.
|
|
20506
|
+
*/
|
|
20507
|
+
class AuthMiddlewareQueue {
|
|
20508
|
+
constructor(auth) {
|
|
20509
|
+
this.auth = auth;
|
|
20510
|
+
this.queue = [];
|
|
20511
|
+
}
|
|
20512
|
+
pushCallback(callback, onAbort) {
|
|
20513
|
+
// The callback could be sync or async. Wrap it into a
|
|
20514
|
+
// function that is always async.
|
|
20515
|
+
const wrappedCallback = (user) => new Promise((resolve, reject) => {
|
|
20516
|
+
try {
|
|
20517
|
+
const result = callback(user);
|
|
20518
|
+
// Either resolve with existing promise or wrap a non-promise
|
|
20519
|
+
// return value into a promise.
|
|
20520
|
+
resolve(result);
|
|
20521
|
+
}
|
|
20522
|
+
catch (e) {
|
|
20523
|
+
// Sync callback throws.
|
|
20524
|
+
reject(e);
|
|
20525
|
+
}
|
|
20526
|
+
});
|
|
20527
|
+
// Attach the onAbort if present
|
|
20528
|
+
wrappedCallback.onAbort = onAbort;
|
|
20529
|
+
this.queue.push(wrappedCallback);
|
|
20530
|
+
const index = this.queue.length - 1;
|
|
20531
|
+
return () => {
|
|
20532
|
+
// Unsubscribe. Replace with no-op. Do not remove from array, or it will disturb
|
|
20533
|
+
// indexing of other elements.
|
|
20534
|
+
this.queue[index] = () => Promise.resolve();
|
|
20535
|
+
};
|
|
20536
|
+
}
|
|
20537
|
+
async runMiddleware(nextUser) {
|
|
20538
|
+
if (this.auth.currentUser === nextUser) {
|
|
20539
|
+
return;
|
|
20540
|
+
}
|
|
20541
|
+
// While running the middleware, build a temporary stack of onAbort
|
|
20542
|
+
// callbacks to call if one middleware callback rejects.
|
|
20543
|
+
const onAbortStack = [];
|
|
20544
|
+
try {
|
|
20545
|
+
for (const beforeStateCallback of this.queue) {
|
|
20546
|
+
await beforeStateCallback(nextUser);
|
|
20547
|
+
// Only push the onAbort if the callback succeeds
|
|
20548
|
+
if (beforeStateCallback.onAbort) {
|
|
20549
|
+
onAbortStack.push(beforeStateCallback.onAbort);
|
|
20550
|
+
}
|
|
20551
|
+
}
|
|
20552
|
+
}
|
|
20553
|
+
catch (e) {
|
|
20554
|
+
// Run all onAbort, with separate try/catch to ignore any errors and
|
|
20555
|
+
// continue
|
|
20556
|
+
onAbortStack.reverse();
|
|
20557
|
+
for (const onAbort of onAbortStack) {
|
|
20558
|
+
try {
|
|
20559
|
+
onAbort();
|
|
20560
|
+
}
|
|
20561
|
+
catch (_) {
|
|
20562
|
+
/* swallow error */
|
|
20563
|
+
}
|
|
20564
|
+
}
|
|
20565
|
+
throw this.auth._errorFactory.create("login-blocked" /* AuthErrorCode.LOGIN_BLOCKED */, {
|
|
20566
|
+
originalMessage: e === null || e === void 0 ? void 0 : e.message
|
|
20567
|
+
});
|
|
20320
20568
|
}
|
|
20321
|
-
// Example response.recaptchaKey: "projects/proj123/keys/sitekey123"
|
|
20322
|
-
this.siteKey = response.recaptchaKey.split('/')[3];
|
|
20323
|
-
this.emailPasswordEnabled = response.recaptchaEnforcementState.some(enforcementState => enforcementState.provider === 'EMAIL_PASSWORD_PROVIDER' &&
|
|
20324
|
-
enforcementState.enforcementState !== 'OFF');
|
|
20325
20569
|
}
|
|
20326
20570
|
}
|
|
20327
20571
|
|
|
20328
20572
|
/**
|
|
20329
20573
|
* @license
|
|
20330
|
-
* Copyright
|
|
20574
|
+
* Copyright 2023 Google LLC
|
|
20331
20575
|
*
|
|
20332
20576
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
20333
20577
|
* you may not use this file except in compliance with the License.
|
|
@@ -20341,232 +20585,162 @@ class RecaptchaConfig {
|
|
|
20341
20585
|
* See the License for the specific language governing permissions and
|
|
20342
20586
|
* limitations under the License.
|
|
20343
20587
|
*/
|
|
20344
|
-
|
|
20345
|
-
|
|
20346
|
-
|
|
20347
|
-
|
|
20348
|
-
|
|
20349
|
-
|
|
20350
|
-
|
|
20351
|
-
|
|
20352
|
-
|
|
20353
|
-
el.onload = resolve;
|
|
20354
|
-
el.onerror = e => {
|
|
20355
|
-
const error = _createError("internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
|
|
20356
|
-
error.customData = e;
|
|
20357
|
-
reject(error);
|
|
20358
|
-
};
|
|
20359
|
-
el.type = 'text/javascript';
|
|
20360
|
-
el.charset = 'UTF-8';
|
|
20361
|
-
getScriptParentElement().appendChild(el);
|
|
20362
|
-
});
|
|
20363
|
-
}
|
|
20364
|
-
function _generateCallbackName(prefix) {
|
|
20365
|
-
return `__${prefix}${Math.floor(Math.random() * 1000000)}`;
|
|
20588
|
+
/**
|
|
20589
|
+
* Fetches the password policy for the currently set tenant or the project if no tenant is set.
|
|
20590
|
+
*
|
|
20591
|
+
* @param auth Auth object.
|
|
20592
|
+
* @param request Password policy request.
|
|
20593
|
+
* @returns Password policy response.
|
|
20594
|
+
*/
|
|
20595
|
+
async function _getPasswordPolicy(auth, request = {}) {
|
|
20596
|
+
return _performApiRequest(auth, "GET" /* HttpMethod.GET */, "/v2/passwordPolicy" /* Endpoint.GET_PASSWORD_POLICY */, _addTidIfNecessary(auth, request));
|
|
20366
20597
|
}
|
|
20367
20598
|
|
|
20368
|
-
|
|
20369
|
-
|
|
20370
|
-
|
|
20371
|
-
|
|
20372
|
-
|
|
20599
|
+
/**
|
|
20600
|
+
* @license
|
|
20601
|
+
* Copyright 2023 Google LLC
|
|
20602
|
+
*
|
|
20603
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
20604
|
+
* you may not use this file except in compliance with the License.
|
|
20605
|
+
* You may obtain a copy of the License at
|
|
20606
|
+
*
|
|
20607
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
20608
|
+
*
|
|
20609
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
20610
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
20611
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
20612
|
+
* See the License for the specific language governing permissions and
|
|
20613
|
+
* limitations under the License.
|
|
20614
|
+
*/
|
|
20615
|
+
// Minimum min password length enforced by the backend, even if no minimum length is set.
|
|
20616
|
+
const MINIMUM_MIN_PASSWORD_LENGTH = 6;
|
|
20617
|
+
/**
|
|
20618
|
+
* Stores password policy requirements and provides password validation against the policy.
|
|
20619
|
+
*
|
|
20620
|
+
* @internal
|
|
20621
|
+
*/
|
|
20622
|
+
class PasswordPolicyImpl {
|
|
20623
|
+
constructor(response) {
|
|
20624
|
+
var _a, _b, _c, _d;
|
|
20625
|
+
// Only include custom strength options defined in the response.
|
|
20626
|
+
const responseOptions = response.customStrengthOptions;
|
|
20627
|
+
this.customStrengthOptions = {};
|
|
20628
|
+
// TODO: Remove once the backend is updated to include the minimum min password length instead of undefined when there is no minimum length set.
|
|
20629
|
+
this.customStrengthOptions.minPasswordLength =
|
|
20630
|
+
(_a = responseOptions.minPasswordLength) !== null && _a !== void 0 ? _a : MINIMUM_MIN_PASSWORD_LENGTH;
|
|
20631
|
+
if (responseOptions.maxPasswordLength) {
|
|
20632
|
+
this.customStrengthOptions.maxPasswordLength =
|
|
20633
|
+
responseOptions.maxPasswordLength;
|
|
20634
|
+
}
|
|
20635
|
+
if (responseOptions.containsLowercaseCharacter !== undefined) {
|
|
20636
|
+
this.customStrengthOptions.containsLowercaseLetter =
|
|
20637
|
+
responseOptions.containsLowercaseCharacter;
|
|
20638
|
+
}
|
|
20639
|
+
if (responseOptions.containsUppercaseCharacter !== undefined) {
|
|
20640
|
+
this.customStrengthOptions.containsUppercaseLetter =
|
|
20641
|
+
responseOptions.containsUppercaseCharacter;
|
|
20642
|
+
}
|
|
20643
|
+
if (responseOptions.containsNumericCharacter !== undefined) {
|
|
20644
|
+
this.customStrengthOptions.containsNumericCharacter =
|
|
20645
|
+
responseOptions.containsNumericCharacter;
|
|
20646
|
+
}
|
|
20647
|
+
if (responseOptions.containsNonAlphanumericCharacter !== undefined) {
|
|
20648
|
+
this.customStrengthOptions.containsNonAlphanumericCharacter =
|
|
20649
|
+
responseOptions.containsNonAlphanumericCharacter;
|
|
20650
|
+
}
|
|
20651
|
+
this.enforcementState = response.enforcementState;
|
|
20652
|
+
if (this.enforcementState === 'ENFORCEMENT_STATE_UNSPECIFIED') {
|
|
20653
|
+
this.enforcementState = 'OFF';
|
|
20654
|
+
}
|
|
20655
|
+
// Use an empty string if no non-alphanumeric characters are specified in the response.
|
|
20656
|
+
this.allowedNonAlphanumericCharacters =
|
|
20657
|
+
(_c = (_b = response.allowedNonAlphanumericCharacters) === null || _b === void 0 ? void 0 : _b.join('')) !== null && _c !== void 0 ? _c : '';
|
|
20658
|
+
this.forceUpgradeOnSignin = (_d = response.forceUpgradeOnSignin) !== null && _d !== void 0 ? _d : false;
|
|
20659
|
+
this.schemaVersion = response.schemaVersion;
|
|
20660
|
+
}
|
|
20661
|
+
validatePassword(password) {
|
|
20662
|
+
var _a, _b, _c, _d, _e, _f;
|
|
20663
|
+
const status = {
|
|
20664
|
+
isValid: true,
|
|
20665
|
+
passwordPolicy: this
|
|
20666
|
+
};
|
|
20667
|
+
// Check the password length and character options.
|
|
20668
|
+
this.validatePasswordLengthOptions(password, status);
|
|
20669
|
+
this.validatePasswordCharacterOptions(password, status);
|
|
20670
|
+
// Combine the status into single isValid property.
|
|
20671
|
+
status.isValid && (status.isValid = (_a = status.meetsMinPasswordLength) !== null && _a !== void 0 ? _a : true);
|
|
20672
|
+
status.isValid && (status.isValid = (_b = status.meetsMaxPasswordLength) !== null && _b !== void 0 ? _b : true);
|
|
20673
|
+
status.isValid && (status.isValid = (_c = status.containsLowercaseLetter) !== null && _c !== void 0 ? _c : true);
|
|
20674
|
+
status.isValid && (status.isValid = (_d = status.containsUppercaseLetter) !== null && _d !== void 0 ? _d : true);
|
|
20675
|
+
status.isValid && (status.isValid = (_e = status.containsNumericCharacter) !== null && _e !== void 0 ? _e : true);
|
|
20676
|
+
status.isValid && (status.isValid = (_f = status.containsNonAlphanumericCharacter) !== null && _f !== void 0 ? _f : true);
|
|
20677
|
+
return status;
|
|
20678
|
+
}
|
|
20373
20679
|
/**
|
|
20680
|
+
* Validates that the password meets the length options for the policy.
|
|
20374
20681
|
*
|
|
20375
|
-
* @param
|
|
20376
|
-
*
|
|
20682
|
+
* @param password Password to validate.
|
|
20683
|
+
* @param status Validation status.
|
|
20377
20684
|
*/
|
|
20378
|
-
|
|
20379
|
-
|
|
20380
|
-
|
|
20381
|
-
|
|
20382
|
-
|
|
20383
|
-
|
|
20685
|
+
validatePasswordLengthOptions(password, status) {
|
|
20686
|
+
const minPasswordLength = this.customStrengthOptions.minPasswordLength;
|
|
20687
|
+
const maxPasswordLength = this.customStrengthOptions.maxPasswordLength;
|
|
20688
|
+
if (minPasswordLength) {
|
|
20689
|
+
status.meetsMinPasswordLength = password.length >= minPasswordLength;
|
|
20690
|
+
}
|
|
20691
|
+
if (maxPasswordLength) {
|
|
20692
|
+
status.meetsMaxPasswordLength = password.length <= maxPasswordLength;
|
|
20693
|
+
}
|
|
20384
20694
|
}
|
|
20385
20695
|
/**
|
|
20386
|
-
*
|
|
20696
|
+
* Validates that the password meets the character options for the policy.
|
|
20387
20697
|
*
|
|
20388
|
-
* @
|
|
20698
|
+
* @param password Password to validate.
|
|
20699
|
+
* @param status Validation status.
|
|
20389
20700
|
*/
|
|
20390
|
-
|
|
20391
|
-
|
|
20392
|
-
|
|
20393
|
-
|
|
20394
|
-
|
|
20395
|
-
|
|
20396
|
-
|
|
20397
|
-
|
|
20398
|
-
|
|
20399
|
-
|
|
20400
|
-
|
|
20401
|
-
|
|
20402
|
-
|
|
20403
|
-
|
|
20404
|
-
|
|
20405
|
-
|
|
20406
|
-
|
|
20407
|
-
|
|
20408
|
-
reject(new Error('recaptcha Enterprise site key undefined'));
|
|
20409
|
-
}
|
|
20410
|
-
else {
|
|
20411
|
-
const config = new RecaptchaConfig(response);
|
|
20412
|
-
if (auth.tenantId == null) {
|
|
20413
|
-
auth._agentRecaptchaConfig = config;
|
|
20414
|
-
}
|
|
20415
|
-
else {
|
|
20416
|
-
auth._tenantRecaptchaConfigs[auth.tenantId] = config;
|
|
20417
|
-
}
|
|
20418
|
-
return resolve(config.siteKey);
|
|
20419
|
-
}
|
|
20420
|
-
})
|
|
20421
|
-
.catch(error => {
|
|
20422
|
-
reject(error);
|
|
20423
|
-
});
|
|
20424
|
-
});
|
|
20701
|
+
validatePasswordCharacterOptions(password, status) {
|
|
20702
|
+
// Assign statuses for requirements even if the password is an empty string.
|
|
20703
|
+
this.updatePasswordCharacterOptionsStatuses(status,
|
|
20704
|
+
/* containsLowercaseCharacter= */ false,
|
|
20705
|
+
/* containsUppercaseCharacter= */ false,
|
|
20706
|
+
/* containsNumericCharacter= */ false,
|
|
20707
|
+
/* containsNonAlphanumericCharacter= */ false);
|
|
20708
|
+
let passwordChar;
|
|
20709
|
+
for (let i = 0; i < password.length; i++) {
|
|
20710
|
+
passwordChar = password.charAt(i);
|
|
20711
|
+
this.updatePasswordCharacterOptionsStatuses(status,
|
|
20712
|
+
/* containsLowercaseCharacter= */ passwordChar >= 'a' &&
|
|
20713
|
+
passwordChar <= 'z',
|
|
20714
|
+
/* containsUppercaseCharacter= */ passwordChar >= 'A' &&
|
|
20715
|
+
passwordChar <= 'Z',
|
|
20716
|
+
/* containsNumericCharacter= */ passwordChar >= '0' &&
|
|
20717
|
+
passwordChar <= '9',
|
|
20718
|
+
/* containsNonAlphanumericCharacter= */ this.allowedNonAlphanumericCharacters.includes(passwordChar));
|
|
20425
20719
|
}
|
|
20426
|
-
function retrieveRecaptchaToken(siteKey, resolve, reject) {
|
|
20427
|
-
const grecaptcha = window.grecaptcha;
|
|
20428
|
-
if (isEnterprise(grecaptcha)) {
|
|
20429
|
-
grecaptcha.enterprise.ready(() => {
|
|
20430
|
-
grecaptcha.enterprise
|
|
20431
|
-
.execute(siteKey, { action })
|
|
20432
|
-
.then(token => {
|
|
20433
|
-
resolve(token);
|
|
20434
|
-
})
|
|
20435
|
-
.catch(() => {
|
|
20436
|
-
resolve(FAKE_TOKEN);
|
|
20437
|
-
});
|
|
20438
|
-
});
|
|
20439
|
-
}
|
|
20440
|
-
else {
|
|
20441
|
-
reject(Error('No reCAPTCHA enterprise script loaded.'));
|
|
20442
|
-
}
|
|
20443
|
-
}
|
|
20444
|
-
return new Promise((resolve, reject) => {
|
|
20445
|
-
retrieveSiteKey(this.auth)
|
|
20446
|
-
.then(siteKey => {
|
|
20447
|
-
if (!forceRefresh && isEnterprise(window.grecaptcha)) {
|
|
20448
|
-
retrieveRecaptchaToken(siteKey, resolve, reject);
|
|
20449
|
-
}
|
|
20450
|
-
else {
|
|
20451
|
-
if (typeof window === 'undefined') {
|
|
20452
|
-
reject(new Error('RecaptchaVerifier is only supported in browser'));
|
|
20453
|
-
return;
|
|
20454
|
-
}
|
|
20455
|
-
_loadJS(RECAPTCHA_ENTERPRISE_URL + siteKey)
|
|
20456
|
-
.then(() => {
|
|
20457
|
-
retrieveRecaptchaToken(siteKey, resolve, reject);
|
|
20458
|
-
})
|
|
20459
|
-
.catch(error => {
|
|
20460
|
-
reject(error);
|
|
20461
|
-
});
|
|
20462
|
-
}
|
|
20463
|
-
})
|
|
20464
|
-
.catch(error => {
|
|
20465
|
-
reject(error);
|
|
20466
|
-
});
|
|
20467
|
-
});
|
|
20468
|
-
}
|
|
20469
|
-
}
|
|
20470
|
-
async function injectRecaptchaFields(auth, request, action, captchaResp = false) {
|
|
20471
|
-
const verifier = new RecaptchaEnterpriseVerifier(auth);
|
|
20472
|
-
let captchaResponse;
|
|
20473
|
-
try {
|
|
20474
|
-
captchaResponse = await verifier.verify(action);
|
|
20475
|
-
}
|
|
20476
|
-
catch (error) {
|
|
20477
|
-
captchaResponse = await verifier.verify(action, true);
|
|
20478
|
-
}
|
|
20479
|
-
const newRequest = Object.assign({}, request);
|
|
20480
|
-
if (!captchaResp) {
|
|
20481
|
-
Object.assign(newRequest, { captchaResponse });
|
|
20482
|
-
}
|
|
20483
|
-
else {
|
|
20484
|
-
Object.assign(newRequest, { 'captchaResp': captchaResponse });
|
|
20485
|
-
}
|
|
20486
|
-
Object.assign(newRequest, { 'clientType': "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */ });
|
|
20487
|
-
Object.assign(newRequest, {
|
|
20488
|
-
'recaptchaVersion': "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
|
|
20489
|
-
});
|
|
20490
|
-
return newRequest;
|
|
20491
|
-
}
|
|
20492
|
-
|
|
20493
|
-
/**
|
|
20494
|
-
* @license
|
|
20495
|
-
* Copyright 2022 Google LLC
|
|
20496
|
-
*
|
|
20497
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
20498
|
-
* you may not use this file except in compliance with the License.
|
|
20499
|
-
* You may obtain a copy of the License at
|
|
20500
|
-
*
|
|
20501
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
20502
|
-
*
|
|
20503
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
20504
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
20505
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
20506
|
-
* See the License for the specific language governing permissions and
|
|
20507
|
-
* limitations under the License.
|
|
20508
|
-
*/
|
|
20509
|
-
class AuthMiddlewareQueue {
|
|
20510
|
-
constructor(auth) {
|
|
20511
|
-
this.auth = auth;
|
|
20512
|
-
this.queue = [];
|
|
20513
20720
|
}
|
|
20514
|
-
|
|
20515
|
-
|
|
20516
|
-
|
|
20517
|
-
|
|
20518
|
-
|
|
20519
|
-
|
|
20520
|
-
|
|
20521
|
-
|
|
20522
|
-
|
|
20523
|
-
|
|
20524
|
-
|
|
20525
|
-
|
|
20526
|
-
|
|
20527
|
-
|
|
20528
|
-
});
|
|
20529
|
-
// Attach the onAbort if present
|
|
20530
|
-
wrappedCallback.onAbort = onAbort;
|
|
20531
|
-
this.queue.push(wrappedCallback);
|
|
20532
|
-
const index = this.queue.length - 1;
|
|
20533
|
-
return () => {
|
|
20534
|
-
// Unsubscribe. Replace with no-op. Do not remove from array, or it will disturb
|
|
20535
|
-
// indexing of other elements.
|
|
20536
|
-
this.queue[index] = () => Promise.resolve();
|
|
20537
|
-
};
|
|
20538
|
-
}
|
|
20539
|
-
async runMiddleware(nextUser) {
|
|
20540
|
-
if (this.auth.currentUser === nextUser) {
|
|
20541
|
-
return;
|
|
20721
|
+
/**
|
|
20722
|
+
* Updates the running validation status with the statuses for the character options.
|
|
20723
|
+
* Expected to be called each time a character is processed to update each option status
|
|
20724
|
+
* based on the current character.
|
|
20725
|
+
*
|
|
20726
|
+
* @param status Validation status.
|
|
20727
|
+
* @param containsLowercaseCharacter Whether the character is a lowercase letter.
|
|
20728
|
+
* @param containsUppercaseCharacter Whether the character is an uppercase letter.
|
|
20729
|
+
* @param containsNumericCharacter Whether the character is a numeric character.
|
|
20730
|
+
* @param containsNonAlphanumericCharacter Whether the character is a non-alphanumeric character.
|
|
20731
|
+
*/
|
|
20732
|
+
updatePasswordCharacterOptionsStatuses(status, containsLowercaseCharacter, containsUppercaseCharacter, containsNumericCharacter, containsNonAlphanumericCharacter) {
|
|
20733
|
+
if (this.customStrengthOptions.containsLowercaseLetter) {
|
|
20734
|
+
status.containsLowercaseLetter || (status.containsLowercaseLetter = containsLowercaseCharacter);
|
|
20542
20735
|
}
|
|
20543
|
-
|
|
20544
|
-
|
|
20545
|
-
const onAbortStack = [];
|
|
20546
|
-
try {
|
|
20547
|
-
for (const beforeStateCallback of this.queue) {
|
|
20548
|
-
await beforeStateCallback(nextUser);
|
|
20549
|
-
// Only push the onAbort if the callback succeeds
|
|
20550
|
-
if (beforeStateCallback.onAbort) {
|
|
20551
|
-
onAbortStack.push(beforeStateCallback.onAbort);
|
|
20552
|
-
}
|
|
20553
|
-
}
|
|
20736
|
+
if (this.customStrengthOptions.containsUppercaseLetter) {
|
|
20737
|
+
status.containsUppercaseLetter || (status.containsUppercaseLetter = containsUppercaseCharacter);
|
|
20554
20738
|
}
|
|
20555
|
-
|
|
20556
|
-
|
|
20557
|
-
|
|
20558
|
-
|
|
20559
|
-
|
|
20560
|
-
try {
|
|
20561
|
-
onAbort();
|
|
20562
|
-
}
|
|
20563
|
-
catch (_) {
|
|
20564
|
-
/* swallow error */
|
|
20565
|
-
}
|
|
20566
|
-
}
|
|
20567
|
-
throw this.auth._errorFactory.create("login-blocked" /* AuthErrorCode.LOGIN_BLOCKED */, {
|
|
20568
|
-
originalMessage: e === null || e === void 0 ? void 0 : e.message
|
|
20569
|
-
});
|
|
20739
|
+
if (this.customStrengthOptions.containsNumericCharacter) {
|
|
20740
|
+
status.containsNumericCharacter || (status.containsNumericCharacter = containsNumericCharacter);
|
|
20741
|
+
}
|
|
20742
|
+
if (this.customStrengthOptions.containsNonAlphanumericCharacter) {
|
|
20743
|
+
status.containsNonAlphanumericCharacter || (status.containsNonAlphanumericCharacter = containsNonAlphanumericCharacter);
|
|
20570
20744
|
}
|
|
20571
20745
|
}
|
|
20572
20746
|
}
|
|
@@ -20601,6 +20775,7 @@ class AuthImpl {
|
|
|
20601
20775
|
this.beforeStateQueue = new AuthMiddlewareQueue(this);
|
|
20602
20776
|
this.redirectUser = null;
|
|
20603
20777
|
this.isProactiveRefreshEnabled = false;
|
|
20778
|
+
this.EXPECTED_PASSWORD_POLICY_SCHEMA_VERSION = 1;
|
|
20604
20779
|
// Any network calls will set this to true and prevent subsequent emulator
|
|
20605
20780
|
// initialization
|
|
20606
20781
|
this._canInitEmulator = true;
|
|
@@ -20611,6 +20786,8 @@ class AuthImpl {
|
|
|
20611
20786
|
this._errorFactory = _DEFAULT_AUTH_ERROR_FACTORY;
|
|
20612
20787
|
this._agentRecaptchaConfig = null;
|
|
20613
20788
|
this._tenantRecaptchaConfigs = {};
|
|
20789
|
+
this._projectPasswordPolicy = null;
|
|
20790
|
+
this._tenantPasswordPolicies = {};
|
|
20614
20791
|
// Tracks the last notified UID for state change listeners to prevent
|
|
20615
20792
|
// repeated calls to the callbacks. Undefined means it's never been
|
|
20616
20793
|
// called, whereas null means it's been called with a signed out user
|
|
@@ -20682,8 +20859,32 @@ class AuthImpl {
|
|
|
20682
20859
|
// Skip blocking callbacks, they should not apply to a change in another tab.
|
|
20683
20860
|
await this._updateCurrentUser(user, /* skipBeforeStateCallbacks */ true);
|
|
20684
20861
|
}
|
|
20862
|
+
async initializeCurrentUserFromIdToken(idToken) {
|
|
20863
|
+
try {
|
|
20864
|
+
const response = await getAccountInfo(this, { idToken });
|
|
20865
|
+
const user = await UserImpl._fromGetAccountInfoResponse(this, response, idToken);
|
|
20866
|
+
await this.directlySetCurrentUser(user);
|
|
20867
|
+
}
|
|
20868
|
+
catch (err) {
|
|
20869
|
+
console.warn('FirebaseServerApp could not login user with provided authIdToken: ', err);
|
|
20870
|
+
await this.directlySetCurrentUser(null);
|
|
20871
|
+
}
|
|
20872
|
+
}
|
|
20685
20873
|
async initializeCurrentUser(popupRedirectResolver) {
|
|
20686
20874
|
var _a;
|
|
20875
|
+
if (_isFirebaseServerApp(this.app)) {
|
|
20876
|
+
const idToken = this.app.settings.authIdToken;
|
|
20877
|
+
if (idToken) {
|
|
20878
|
+
// Start the auth operation in the next tick to allow a moment for the customer's app to
|
|
20879
|
+
// attach an emulator, if desired.
|
|
20880
|
+
return new Promise(resolve => {
|
|
20881
|
+
setTimeout(() => this.initializeCurrentUserFromIdToken(idToken).then(resolve, resolve));
|
|
20882
|
+
});
|
|
20883
|
+
}
|
|
20884
|
+
else {
|
|
20885
|
+
return this.directlySetCurrentUser(null);
|
|
20886
|
+
}
|
|
20887
|
+
}
|
|
20687
20888
|
// First check to see if we have a pending redirect event.
|
|
20688
20889
|
const previouslyStoredUser = (await this.assertedPersistence.getCurrentUser());
|
|
20689
20890
|
let futureCurrentUser = previouslyStoredUser;
|
|
@@ -20789,6 +20990,9 @@ class AuthImpl {
|
|
|
20789
20990
|
this._deleted = true;
|
|
20790
20991
|
}
|
|
20791
20992
|
async updateCurrentUser(userExtern) {
|
|
20993
|
+
if (_isFirebaseServerApp(this.app)) {
|
|
20994
|
+
return Promise.reject(_serverAppCurrentUserOperationNotSupportedError(this));
|
|
20995
|
+
}
|
|
20792
20996
|
// The public updateCurrentUser method needs to make a copy of the user,
|
|
20793
20997
|
// and also check that the project matches
|
|
20794
20998
|
const user = userExtern
|
|
@@ -20815,6 +21019,9 @@ class AuthImpl {
|
|
|
20815
21019
|
});
|
|
20816
21020
|
}
|
|
20817
21021
|
async signOut() {
|
|
21022
|
+
if (_isFirebaseServerApp(this.app)) {
|
|
21023
|
+
return Promise.reject(_serverAppCurrentUserOperationNotSupportedError(this));
|
|
21024
|
+
}
|
|
20818
21025
|
// Run first, to block _setRedirectUser() if any callbacks fail.
|
|
20819
21026
|
await this.beforeStateQueue.runMiddleware(null);
|
|
20820
21027
|
// Clear the redirect user when signOut is called
|
|
@@ -20826,33 +21033,51 @@ class AuthImpl {
|
|
|
20826
21033
|
return this._updateCurrentUser(null, /* skipBeforeStateCallbacks */ true);
|
|
20827
21034
|
}
|
|
20828
21035
|
setPersistence(persistence) {
|
|
21036
|
+
if (_isFirebaseServerApp(this.app)) {
|
|
21037
|
+
return Promise.reject(_serverAppCurrentUserOperationNotSupportedError(this));
|
|
21038
|
+
}
|
|
20829
21039
|
return this.queue(async () => {
|
|
20830
21040
|
await this.assertedPersistence.setPersistence(_getInstance(persistence));
|
|
20831
21041
|
});
|
|
20832
21042
|
}
|
|
20833
|
-
|
|
20834
|
-
const response = await getRecaptchaConfig(this, {
|
|
20835
|
-
clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */,
|
|
20836
|
-
version: "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
|
|
20837
|
-
});
|
|
20838
|
-
const config = new RecaptchaConfig(response);
|
|
21043
|
+
_getRecaptchaConfig() {
|
|
20839
21044
|
if (this.tenantId == null) {
|
|
20840
|
-
this._agentRecaptchaConfig
|
|
21045
|
+
return this._agentRecaptchaConfig;
|
|
20841
21046
|
}
|
|
20842
21047
|
else {
|
|
20843
|
-
this._tenantRecaptchaConfigs[this.tenantId]
|
|
21048
|
+
return this._tenantRecaptchaConfigs[this.tenantId];
|
|
21049
|
+
}
|
|
21050
|
+
}
|
|
21051
|
+
async validatePassword(password) {
|
|
21052
|
+
if (!this._getPasswordPolicyInternal()) {
|
|
21053
|
+
await this._updatePasswordPolicy();
|
|
20844
21054
|
}
|
|
20845
|
-
|
|
20846
|
-
|
|
20847
|
-
|
|
21055
|
+
// Password policy will be defined after fetching.
|
|
21056
|
+
const passwordPolicy = this._getPasswordPolicyInternal();
|
|
21057
|
+
// Check that the policy schema version is supported by the SDK.
|
|
21058
|
+
// TODO: Update this logic to use a max supported policy schema version once we have multiple schema versions.
|
|
21059
|
+
if (passwordPolicy.schemaVersion !==
|
|
21060
|
+
this.EXPECTED_PASSWORD_POLICY_SCHEMA_VERSION) {
|
|
21061
|
+
return Promise.reject(this._errorFactory.create("unsupported-password-policy-schema-version" /* AuthErrorCode.UNSUPPORTED_PASSWORD_POLICY_SCHEMA_VERSION */, {}));
|
|
20848
21062
|
}
|
|
21063
|
+
return passwordPolicy.validatePassword(password);
|
|
20849
21064
|
}
|
|
20850
|
-
|
|
20851
|
-
if (this.tenantId
|
|
20852
|
-
return this.
|
|
21065
|
+
_getPasswordPolicyInternal() {
|
|
21066
|
+
if (this.tenantId === null) {
|
|
21067
|
+
return this._projectPasswordPolicy;
|
|
20853
21068
|
}
|
|
20854
21069
|
else {
|
|
20855
|
-
return this.
|
|
21070
|
+
return this._tenantPasswordPolicies[this.tenantId];
|
|
21071
|
+
}
|
|
21072
|
+
}
|
|
21073
|
+
async _updatePasswordPolicy() {
|
|
21074
|
+
const response = await _getPasswordPolicy(this);
|
|
21075
|
+
const passwordPolicy = new PasswordPolicyImpl(response);
|
|
21076
|
+
if (this.tenantId === null) {
|
|
21077
|
+
this._projectPasswordPolicy = passwordPolicy;
|
|
21078
|
+
}
|
|
21079
|
+
else {
|
|
21080
|
+
this._tenantPasswordPolicies[this.tenantId] = passwordPolicy;
|
|
20856
21081
|
}
|
|
20857
21082
|
}
|
|
20858
21083
|
_getPersistence() {
|
|
@@ -20870,6 +21095,38 @@ class AuthImpl {
|
|
|
20870
21095
|
onIdTokenChanged(nextOrObserver, error, completed) {
|
|
20871
21096
|
return this.registerStateListener(this.idTokenSubscription, nextOrObserver, error, completed);
|
|
20872
21097
|
}
|
|
21098
|
+
authStateReady() {
|
|
21099
|
+
return new Promise((resolve, reject) => {
|
|
21100
|
+
if (this.currentUser) {
|
|
21101
|
+
resolve();
|
|
21102
|
+
}
|
|
21103
|
+
else {
|
|
21104
|
+
const unsubscribe = this.onAuthStateChanged(() => {
|
|
21105
|
+
unsubscribe();
|
|
21106
|
+
resolve();
|
|
21107
|
+
}, reject);
|
|
21108
|
+
}
|
|
21109
|
+
});
|
|
21110
|
+
}
|
|
21111
|
+
/**
|
|
21112
|
+
* Revokes the given access token. Currently only supports Apple OAuth access tokens.
|
|
21113
|
+
*/
|
|
21114
|
+
async revokeAccessToken(token) {
|
|
21115
|
+
if (this.currentUser) {
|
|
21116
|
+
const idToken = await this.currentUser.getIdToken();
|
|
21117
|
+
// Generalize this to accept other providers once supported.
|
|
21118
|
+
const request = {
|
|
21119
|
+
providerId: 'apple.com',
|
|
21120
|
+
tokenType: "ACCESS_TOKEN" /* TokenType.ACCESS_TOKEN */,
|
|
21121
|
+
token,
|
|
21122
|
+
idToken
|
|
21123
|
+
};
|
|
21124
|
+
if (this.tenantId != null) {
|
|
21125
|
+
request.tenantId = this.tenantId;
|
|
21126
|
+
}
|
|
21127
|
+
await revokeToken(this, request);
|
|
21128
|
+
}
|
|
21129
|
+
}
|
|
20873
21130
|
toJSON() {
|
|
20874
21131
|
var _a;
|
|
20875
21132
|
return {
|
|
@@ -20960,18 +21217,32 @@ class AuthImpl {
|
|
|
20960
21217
|
const cb = typeof nextOrObserver === 'function'
|
|
20961
21218
|
? nextOrObserver
|
|
20962
21219
|
: nextOrObserver.next.bind(nextOrObserver);
|
|
21220
|
+
let isUnsubscribed = false;
|
|
20963
21221
|
const promise = this._isInitialized
|
|
20964
21222
|
? Promise.resolve()
|
|
20965
21223
|
: this._initializationPromise;
|
|
20966
21224
|
_assert(promise, this, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
|
|
20967
21225
|
// The callback needs to be called asynchronously per the spec.
|
|
20968
21226
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
20969
|
-
promise.then(() =>
|
|
21227
|
+
promise.then(() => {
|
|
21228
|
+
if (isUnsubscribed) {
|
|
21229
|
+
return;
|
|
21230
|
+
}
|
|
21231
|
+
cb(this.currentUser);
|
|
21232
|
+
});
|
|
20970
21233
|
if (typeof nextOrObserver === 'function') {
|
|
20971
|
-
|
|
21234
|
+
const unsubscribe = subscription.addObserver(nextOrObserver, error, completed);
|
|
21235
|
+
return () => {
|
|
21236
|
+
isUnsubscribed = true;
|
|
21237
|
+
unsubscribe();
|
|
21238
|
+
};
|
|
20972
21239
|
}
|
|
20973
21240
|
else {
|
|
20974
|
-
|
|
21241
|
+
const unsubscribe = subscription.addObserver(nextOrObserver);
|
|
21242
|
+
return () => {
|
|
21243
|
+
isUnsubscribed = true;
|
|
21244
|
+
unsubscribe();
|
|
21245
|
+
};
|
|
20975
21246
|
}
|
|
20976
21247
|
}
|
|
20977
21248
|
/**
|
|
@@ -21056,7 +21327,7 @@ class AuthImpl {
|
|
|
21056
21327
|
}
|
|
21057
21328
|
}
|
|
21058
21329
|
/**
|
|
21059
|
-
* Method to be used to cast down to our private
|
|
21330
|
+
* Method to be used to cast down to our private implementation of Auth.
|
|
21060
21331
|
* It will also handle unwrapping from the compat type if necessary
|
|
21061
21332
|
*
|
|
21062
21333
|
* @param auth Auth object passed in from developer
|
|
@@ -21077,6 +21348,194 @@ class Subscription {
|
|
|
21077
21348
|
}
|
|
21078
21349
|
}
|
|
21079
21350
|
|
|
21351
|
+
/**
|
|
21352
|
+
* @license
|
|
21353
|
+
* Copyright 2020 Google LLC
|
|
21354
|
+
*
|
|
21355
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
21356
|
+
* you may not use this file except in compliance with the License.
|
|
21357
|
+
* You may obtain a copy of the License at
|
|
21358
|
+
*
|
|
21359
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
21360
|
+
*
|
|
21361
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
21362
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
21363
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
21364
|
+
* See the License for the specific language governing permissions and
|
|
21365
|
+
* limitations under the License.
|
|
21366
|
+
*/
|
|
21367
|
+
let externalJSProvider = {
|
|
21368
|
+
async loadJS() {
|
|
21369
|
+
throw new Error('Unable to load external scripts');
|
|
21370
|
+
},
|
|
21371
|
+
recaptchaV2Script: '',
|
|
21372
|
+
recaptchaEnterpriseScript: '',
|
|
21373
|
+
gapiScript: ''
|
|
21374
|
+
};
|
|
21375
|
+
function _setExternalJSProvider(p) {
|
|
21376
|
+
externalJSProvider = p;
|
|
21377
|
+
}
|
|
21378
|
+
function _loadJS(url) {
|
|
21379
|
+
return externalJSProvider.loadJS(url);
|
|
21380
|
+
}
|
|
21381
|
+
function _recaptchaEnterpriseScriptUrl() {
|
|
21382
|
+
return externalJSProvider.recaptchaEnterpriseScript;
|
|
21383
|
+
}
|
|
21384
|
+
function _gapiScriptUrl() {
|
|
21385
|
+
return externalJSProvider.gapiScript;
|
|
21386
|
+
}
|
|
21387
|
+
function _generateCallbackName(prefix) {
|
|
21388
|
+
return `__${prefix}${Math.floor(Math.random() * 1000000)}`;
|
|
21389
|
+
}
|
|
21390
|
+
|
|
21391
|
+
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
21392
|
+
const RECAPTCHA_ENTERPRISE_VERIFIER_TYPE = 'recaptcha-enterprise';
|
|
21393
|
+
const FAKE_TOKEN = 'NO_RECAPTCHA';
|
|
21394
|
+
class RecaptchaEnterpriseVerifier {
|
|
21395
|
+
/**
|
|
21396
|
+
*
|
|
21397
|
+
* @param authExtern - The corresponding Firebase {@link Auth} instance.
|
|
21398
|
+
*
|
|
21399
|
+
*/
|
|
21400
|
+
constructor(authExtern) {
|
|
21401
|
+
/**
|
|
21402
|
+
* Identifies the type of application verifier (e.g. "recaptcha-enterprise").
|
|
21403
|
+
*/
|
|
21404
|
+
this.type = RECAPTCHA_ENTERPRISE_VERIFIER_TYPE;
|
|
21405
|
+
this.auth = _castAuth(authExtern);
|
|
21406
|
+
}
|
|
21407
|
+
/**
|
|
21408
|
+
* Executes the verification process.
|
|
21409
|
+
*
|
|
21410
|
+
* @returns A Promise for a token that can be used to assert the validity of a request.
|
|
21411
|
+
*/
|
|
21412
|
+
async verify(action = 'verify', forceRefresh = false) {
|
|
21413
|
+
async function retrieveSiteKey(auth) {
|
|
21414
|
+
if (!forceRefresh) {
|
|
21415
|
+
if (auth.tenantId == null && auth._agentRecaptchaConfig != null) {
|
|
21416
|
+
return auth._agentRecaptchaConfig.siteKey;
|
|
21417
|
+
}
|
|
21418
|
+
if (auth.tenantId != null &&
|
|
21419
|
+
auth._tenantRecaptchaConfigs[auth.tenantId] !== undefined) {
|
|
21420
|
+
return auth._tenantRecaptchaConfigs[auth.tenantId].siteKey;
|
|
21421
|
+
}
|
|
21422
|
+
}
|
|
21423
|
+
return new Promise(async (resolve, reject) => {
|
|
21424
|
+
getRecaptchaConfig(auth, {
|
|
21425
|
+
clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */,
|
|
21426
|
+
version: "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
|
|
21427
|
+
})
|
|
21428
|
+
.then(response => {
|
|
21429
|
+
if (response.recaptchaKey === undefined) {
|
|
21430
|
+
reject(new Error('recaptcha Enterprise site key undefined'));
|
|
21431
|
+
}
|
|
21432
|
+
else {
|
|
21433
|
+
const config = new RecaptchaConfig(response);
|
|
21434
|
+
if (auth.tenantId == null) {
|
|
21435
|
+
auth._agentRecaptchaConfig = config;
|
|
21436
|
+
}
|
|
21437
|
+
else {
|
|
21438
|
+
auth._tenantRecaptchaConfigs[auth.tenantId] = config;
|
|
21439
|
+
}
|
|
21440
|
+
return resolve(config.siteKey);
|
|
21441
|
+
}
|
|
21442
|
+
})
|
|
21443
|
+
.catch(error => {
|
|
21444
|
+
reject(error);
|
|
21445
|
+
});
|
|
21446
|
+
});
|
|
21447
|
+
}
|
|
21448
|
+
function retrieveRecaptchaToken(siteKey, resolve, reject) {
|
|
21449
|
+
const grecaptcha = window.grecaptcha;
|
|
21450
|
+
if (isEnterprise(grecaptcha)) {
|
|
21451
|
+
grecaptcha.enterprise.ready(() => {
|
|
21452
|
+
grecaptcha.enterprise
|
|
21453
|
+
.execute(siteKey, { action })
|
|
21454
|
+
.then(token => {
|
|
21455
|
+
resolve(token);
|
|
21456
|
+
})
|
|
21457
|
+
.catch(() => {
|
|
21458
|
+
resolve(FAKE_TOKEN);
|
|
21459
|
+
});
|
|
21460
|
+
});
|
|
21461
|
+
}
|
|
21462
|
+
else {
|
|
21463
|
+
reject(Error('No reCAPTCHA enterprise script loaded.'));
|
|
21464
|
+
}
|
|
21465
|
+
}
|
|
21466
|
+
return new Promise((resolve, reject) => {
|
|
21467
|
+
retrieveSiteKey(this.auth)
|
|
21468
|
+
.then(siteKey => {
|
|
21469
|
+
if (!forceRefresh && isEnterprise(window.grecaptcha)) {
|
|
21470
|
+
retrieveRecaptchaToken(siteKey, resolve, reject);
|
|
21471
|
+
}
|
|
21472
|
+
else {
|
|
21473
|
+
if (typeof window === 'undefined') {
|
|
21474
|
+
reject(new Error('RecaptchaVerifier is only supported in browser'));
|
|
21475
|
+
return;
|
|
21476
|
+
}
|
|
21477
|
+
let url = _recaptchaEnterpriseScriptUrl();
|
|
21478
|
+
if (url.length !== 0) {
|
|
21479
|
+
url += siteKey;
|
|
21480
|
+
}
|
|
21481
|
+
_loadJS(url)
|
|
21482
|
+
.then(() => {
|
|
21483
|
+
retrieveRecaptchaToken(siteKey, resolve, reject);
|
|
21484
|
+
})
|
|
21485
|
+
.catch(error => {
|
|
21486
|
+
reject(error);
|
|
21487
|
+
});
|
|
21488
|
+
}
|
|
21489
|
+
})
|
|
21490
|
+
.catch(error => {
|
|
21491
|
+
reject(error);
|
|
21492
|
+
});
|
|
21493
|
+
});
|
|
21494
|
+
}
|
|
21495
|
+
}
|
|
21496
|
+
async function injectRecaptchaFields(auth, request, action, captchaResp = false) {
|
|
21497
|
+
const verifier = new RecaptchaEnterpriseVerifier(auth);
|
|
21498
|
+
let captchaResponse;
|
|
21499
|
+
try {
|
|
21500
|
+
captchaResponse = await verifier.verify(action);
|
|
21501
|
+
}
|
|
21502
|
+
catch (error) {
|
|
21503
|
+
captchaResponse = await verifier.verify(action, true);
|
|
21504
|
+
}
|
|
21505
|
+
const newRequest = Object.assign({}, request);
|
|
21506
|
+
if (!captchaResp) {
|
|
21507
|
+
Object.assign(newRequest, { captchaResponse });
|
|
21508
|
+
}
|
|
21509
|
+
else {
|
|
21510
|
+
Object.assign(newRequest, { 'captchaResp': captchaResponse });
|
|
21511
|
+
}
|
|
21512
|
+
Object.assign(newRequest, { 'clientType': "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */ });
|
|
21513
|
+
Object.assign(newRequest, {
|
|
21514
|
+
'recaptchaVersion': "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
|
|
21515
|
+
});
|
|
21516
|
+
return newRequest;
|
|
21517
|
+
}
|
|
21518
|
+
async function handleRecaptchaFlow(authInstance, request, actionName, actionMethod) {
|
|
21519
|
+
var _a;
|
|
21520
|
+
if ((_a = authInstance
|
|
21521
|
+
._getRecaptchaConfig()) === null || _a === void 0 ? void 0 : _a.isProviderEnabled("EMAIL_PASSWORD_PROVIDER" /* RecaptchaProvider.EMAIL_PASSWORD_PROVIDER */)) {
|
|
21522
|
+
const requestWithRecaptcha = await injectRecaptchaFields(authInstance, request, actionName, actionName === "getOobCode" /* RecaptchaActionName.GET_OOB_CODE */);
|
|
21523
|
+
return actionMethod(authInstance, requestWithRecaptcha);
|
|
21524
|
+
}
|
|
21525
|
+
else {
|
|
21526
|
+
return actionMethod(authInstance, request).catch(async (error) => {
|
|
21527
|
+
if (error.code === `auth/${"missing-recaptcha-token" /* AuthErrorCode.MISSING_RECAPTCHA_TOKEN */}`) {
|
|
21528
|
+
console.log(`${actionName} is protected by reCAPTCHA Enterprise for this project. Automatically triggering the reCAPTCHA flow and restarting the flow.`);
|
|
21529
|
+
const requestWithRecaptcha = await injectRecaptchaFields(authInstance, request, actionName, actionName === "getOobCode" /* RecaptchaActionName.GET_OOB_CODE */);
|
|
21530
|
+
return actionMethod(authInstance, requestWithRecaptcha);
|
|
21531
|
+
}
|
|
21532
|
+
else {
|
|
21533
|
+
return Promise.reject(error);
|
|
21534
|
+
}
|
|
21535
|
+
});
|
|
21536
|
+
}
|
|
21537
|
+
}
|
|
21538
|
+
|
|
21080
21539
|
/**
|
|
21081
21540
|
* @license
|
|
21082
21541
|
* Copyright 2020 Google LLC
|
|
@@ -21340,8 +21799,10 @@ class AuthCredential {
|
|
|
21340
21799
|
async function resetPassword(auth, request) {
|
|
21341
21800
|
return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:resetPassword" /* Endpoint.RESET_PASSWORD */, _addTidIfNecessary(auth, request));
|
|
21342
21801
|
}
|
|
21343
|
-
|
|
21344
|
-
|
|
21802
|
+
// Used for linking an email/password account to an existing idToken. Uses the same request/response
|
|
21803
|
+
// format as updateEmailPassword.
|
|
21804
|
+
async function linkEmailPassword(auth, request) {
|
|
21805
|
+
return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:signUp" /* Endpoint.SIGN_UP */, request);
|
|
21345
21806
|
}
|
|
21346
21807
|
|
|
21347
21808
|
/**
|
|
@@ -21472,7 +21933,6 @@ class EmailAuthCredential extends AuthCredential {
|
|
|
21472
21933
|
}
|
|
21473
21934
|
/** @internal */
|
|
21474
21935
|
async _getIdTokenResponse(auth) {
|
|
21475
|
-
var _a;
|
|
21476
21936
|
switch (this.signInMethod) {
|
|
21477
21937
|
case "password" /* SignInMethod.EMAIL_PASSWORD */:
|
|
21478
21938
|
const request = {
|
|
@@ -21481,22 +21941,7 @@ class EmailAuthCredential extends AuthCredential {
|
|
|
21481
21941
|
password: this._password,
|
|
21482
21942
|
clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */
|
|
21483
21943
|
};
|
|
21484
|
-
|
|
21485
|
-
const requestWithRecaptcha = await injectRecaptchaFields(auth, request, "signInWithPassword" /* RecaptchaActionName.SIGN_IN_WITH_PASSWORD */);
|
|
21486
|
-
return signInWithPassword(auth, requestWithRecaptcha);
|
|
21487
|
-
}
|
|
21488
|
-
else {
|
|
21489
|
-
return signInWithPassword(auth, request).catch(async (error) => {
|
|
21490
|
-
if (error.code === `auth/${"missing-recaptcha-token" /* AuthErrorCode.MISSING_RECAPTCHA_TOKEN */}`) {
|
|
21491
|
-
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.');
|
|
21492
|
-
const requestWithRecaptcha = await injectRecaptchaFields(auth, request, "signInWithPassword" /* RecaptchaActionName.SIGN_IN_WITH_PASSWORD */);
|
|
21493
|
-
return signInWithPassword(auth, requestWithRecaptcha);
|
|
21494
|
-
}
|
|
21495
|
-
else {
|
|
21496
|
-
return Promise.reject(error);
|
|
21497
|
-
}
|
|
21498
|
-
});
|
|
21499
|
-
}
|
|
21944
|
+
return handleRecaptchaFlow(auth, request, "signInWithPassword" /* RecaptchaActionName.SIGN_IN_WITH_PASSWORD */, signInWithPassword);
|
|
21500
21945
|
case "emailLink" /* SignInMethod.EMAIL_LINK */:
|
|
21501
21946
|
return signInWithEmailLink$1(auth, {
|
|
21502
21947
|
email: this._email,
|
|
@@ -21510,12 +21955,14 @@ class EmailAuthCredential extends AuthCredential {
|
|
|
21510
21955
|
async _linkToIdToken(auth, idToken) {
|
|
21511
21956
|
switch (this.signInMethod) {
|
|
21512
21957
|
case "password" /* SignInMethod.EMAIL_PASSWORD */:
|
|
21513
|
-
|
|
21958
|
+
const request = {
|
|
21514
21959
|
idToken,
|
|
21515
21960
|
returnSecureToken: true,
|
|
21516
21961
|
email: this._email,
|
|
21517
|
-
password: this._password
|
|
21518
|
-
|
|
21962
|
+
password: this._password,
|
|
21963
|
+
clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */
|
|
21964
|
+
};
|
|
21965
|
+
return handleRecaptchaFlow(auth, request, "signUpPassword" /* RecaptchaActionName.SIGN_UP_PASSWORD */, linkEmailPassword);
|
|
21519
21966
|
case "emailLink" /* SignInMethod.EMAIL_LINK */:
|
|
21520
21967
|
return signInWithEmailLinkForLinking(auth, {
|
|
21521
21968
|
idToken,
|
|
@@ -22133,7 +22580,7 @@ FacebookAuthProvider.PROVIDER_ID = "facebook.com" /* ProviderId.FACEBOOK */;
|
|
|
22133
22580
|
* limitations under the License.
|
|
22134
22581
|
*/
|
|
22135
22582
|
/**
|
|
22136
|
-
* Provider for generating an
|
|
22583
|
+
* Provider for generating an {@link OAuthCredential} for {@link ProviderId}.GOOGLE.
|
|
22137
22584
|
*
|
|
22138
22585
|
* @example
|
|
22139
22586
|
* ```javascript
|
|
@@ -22275,7 +22722,7 @@ GoogleAuthProvider.PROVIDER_ID = "google.com" /* ProviderId.GOOGLE */;
|
|
|
22275
22722
|
* if (result) {
|
|
22276
22723
|
* // This is the signed-in user
|
|
22277
22724
|
* const user = result.user;
|
|
22278
|
-
* // This gives you a
|
|
22725
|
+
* // This gives you a GitHub Access Token.
|
|
22279
22726
|
* const credential = GithubAuthProvider.credentialFromResult(result);
|
|
22280
22727
|
* const token = credential.accessToken;
|
|
22281
22728
|
* }
|
|
@@ -22290,7 +22737,7 @@ GoogleAuthProvider.PROVIDER_ID = "google.com" /* ProviderId.GOOGLE */;
|
|
|
22290
22737
|
*
|
|
22291
22738
|
* // The signed-in user info.
|
|
22292
22739
|
* const user = result.user;
|
|
22293
|
-
* // This gives you a
|
|
22740
|
+
* // This gives you a GitHub Access Token.
|
|
22294
22741
|
* const credential = GithubAuthProvider.credentialFromResult(result);
|
|
22295
22742
|
* const token = credential.accessToken;
|
|
22296
22743
|
* ```
|
|
@@ -22301,9 +22748,9 @@ class GithubAuthProvider extends BaseOAuthProvider {
|
|
|
22301
22748
|
super("github.com" /* ProviderId.GITHUB */);
|
|
22302
22749
|
}
|
|
22303
22750
|
/**
|
|
22304
|
-
* Creates a credential for
|
|
22751
|
+
* Creates a credential for GitHub.
|
|
22305
22752
|
*
|
|
22306
|
-
* @param accessToken -
|
|
22753
|
+
* @param accessToken - GitHub access token.
|
|
22307
22754
|
*/
|
|
22308
22755
|
static credential(accessToken) {
|
|
22309
22756
|
return OAuthCredential._fromParams({
|
|
@@ -22584,6 +23031,9 @@ async function _link$1(user, credential, bypassAuthState = false) {
|
|
|
22584
23031
|
*/
|
|
22585
23032
|
async function _reauthenticate(user, credential, bypassAuthState = false) {
|
|
22586
23033
|
const { auth } = user;
|
|
23034
|
+
if (_isFirebaseServerApp(auth.app)) {
|
|
23035
|
+
return Promise.reject(_serverAppCurrentUserOperationNotSupportedError(auth));
|
|
23036
|
+
}
|
|
22587
23037
|
const operationType = "reauthenticate" /* OperationType.REAUTHENTICATE */;
|
|
22588
23038
|
try {
|
|
22589
23039
|
const response = await _logoutIfInvalidated(user, _processCredentialSavingMfaContextIfNecessary(auth, operationType, credential, user), bypassAuthState);
|
|
@@ -22620,6 +23070,9 @@ async function _reauthenticate(user, credential, bypassAuthState = false) {
|
|
|
22620
23070
|
* limitations under the License.
|
|
22621
23071
|
*/
|
|
22622
23072
|
async function _signInWithCredential(auth, credential, bypassAuthState = false) {
|
|
23073
|
+
if (_isFirebaseServerApp(auth.app)) {
|
|
23074
|
+
return Promise.reject(_serverAppCurrentUserOperationNotSupportedError(auth));
|
|
23075
|
+
}
|
|
22623
23076
|
const operationType = "signIn" /* OperationType.SIGN_IN */;
|
|
22624
23077
|
const response = await _processCredentialSavingMfaContextIfNecessary(auth, operationType, credential);
|
|
22625
23078
|
const userCredential = await UserCredentialImpl._fromIdTokenResponse(auth, operationType, response);
|
|
@@ -22634,6 +23087,9 @@ async function _signInWithCredential(auth, credential, bypassAuthState = false)
|
|
|
22634
23087
|
* @remarks
|
|
22635
23088
|
* An {@link AuthProvider} can be used to generate the credential.
|
|
22636
23089
|
*
|
|
23090
|
+
* This method is not supported by {@link Auth} instances created with a
|
|
23091
|
+
* {@link @firebase/app#FirebaseServerApp}.
|
|
23092
|
+
*
|
|
22637
23093
|
* @param auth - The {@link Auth} instance.
|
|
22638
23094
|
* @param credential - The auth credential.
|
|
22639
23095
|
*
|
|
@@ -22697,7 +23153,29 @@ function _setActionCodeSettingsOnRequest(auth, request, actionCodeSettings) {
|
|
|
22697
23153
|
* limitations under the License.
|
|
22698
23154
|
*/
|
|
22699
23155
|
/**
|
|
22700
|
-
*
|
|
23156
|
+
* Updates the password policy cached in the {@link Auth} instance if a policy is already
|
|
23157
|
+
* cached for the project or tenant.
|
|
23158
|
+
*
|
|
23159
|
+
* @remarks
|
|
23160
|
+
* We only fetch the password policy if the password did not meet policy requirements and
|
|
23161
|
+
* there is an existing policy cached. A developer must call validatePassword at least
|
|
23162
|
+
* once for the cache to be automatically updated.
|
|
23163
|
+
*
|
|
23164
|
+
* @param auth - The {@link Auth} instance.
|
|
23165
|
+
*
|
|
23166
|
+
* @private
|
|
23167
|
+
*/
|
|
23168
|
+
async function recachePasswordPolicy(auth) {
|
|
23169
|
+
const authInternal = _castAuth(auth);
|
|
23170
|
+
if (authInternal._getPasswordPolicyInternal()) {
|
|
23171
|
+
await authInternal._updatePasswordPolicy();
|
|
23172
|
+
}
|
|
23173
|
+
}
|
|
23174
|
+
/**
|
|
23175
|
+
* Sends a password reset email to the given email address. This method does not throw an error when
|
|
23176
|
+
* there's no user account with the given email address and
|
|
23177
|
+
* {@link https://cloud.google.com/identity-platform/docs/admin/email-enumeration-protection | Email Enumeration Protection}
|
|
23178
|
+
* is enabled.
|
|
22701
23179
|
*
|
|
22702
23180
|
* @remarks
|
|
22703
23181
|
* To complete the password reset, call {@link confirmPasswordReset} with the code supplied in
|
|
@@ -22729,39 +23207,16 @@ function _setActionCodeSettingsOnRequest(auth, request, actionCodeSettings) {
|
|
|
22729
23207
|
* @public
|
|
22730
23208
|
*/
|
|
22731
23209
|
async function sendPasswordResetEmail(auth, email, actionCodeSettings) {
|
|
22732
|
-
var _a;
|
|
22733
23210
|
const authInternal = _castAuth(auth);
|
|
22734
23211
|
const request = {
|
|
22735
23212
|
requestType: "PASSWORD_RESET" /* ActionCodeOperation.PASSWORD_RESET */,
|
|
22736
23213
|
email,
|
|
22737
23214
|
clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */
|
|
22738
23215
|
};
|
|
22739
|
-
if (
|
|
22740
|
-
|
|
22741
|
-
if (actionCodeSettings) {
|
|
22742
|
-
_setActionCodeSettingsOnRequest(authInternal, requestWithRecaptcha, actionCodeSettings);
|
|
22743
|
-
}
|
|
22744
|
-
await sendPasswordResetEmail$1(authInternal, requestWithRecaptcha);
|
|
22745
|
-
}
|
|
22746
|
-
else {
|
|
22747
|
-
if (actionCodeSettings) {
|
|
22748
|
-
_setActionCodeSettingsOnRequest(authInternal, request, actionCodeSettings);
|
|
22749
|
-
}
|
|
22750
|
-
await sendPasswordResetEmail$1(authInternal, request)
|
|
22751
|
-
.catch(async (error) => {
|
|
22752
|
-
if (error.code === `auth/${"missing-recaptcha-token" /* AuthErrorCode.MISSING_RECAPTCHA_TOKEN */}`) {
|
|
22753
|
-
console.log('Password resets are protected by reCAPTCHA for this project. Automatically triggering the reCAPTCHA flow and restarting the password reset flow.');
|
|
22754
|
-
const requestWithRecaptcha = await injectRecaptchaFields(authInternal, request, "getOobCode" /* RecaptchaActionName.GET_OOB_CODE */, true);
|
|
22755
|
-
if (actionCodeSettings) {
|
|
22756
|
-
_setActionCodeSettingsOnRequest(authInternal, requestWithRecaptcha, actionCodeSettings);
|
|
22757
|
-
}
|
|
22758
|
-
await sendPasswordResetEmail$1(authInternal, requestWithRecaptcha);
|
|
22759
|
-
}
|
|
22760
|
-
else {
|
|
22761
|
-
return Promise.reject(error);
|
|
22762
|
-
}
|
|
22763
|
-
});
|
|
23216
|
+
if (actionCodeSettings) {
|
|
23217
|
+
_setActionCodeSettingsOnRequest(authInternal, request, actionCodeSettings);
|
|
22764
23218
|
}
|
|
23219
|
+
await handleRecaptchaFlow(authInternal, request, "getOobCode" /* RecaptchaActionName.GET_OOB_CODE */, sendPasswordResetEmail$1);
|
|
22765
23220
|
}
|
|
22766
23221
|
/**
|
|
22767
23222
|
* Completes the password reset process, given a confirmation code and new password.
|
|
@@ -22776,6 +23231,13 @@ async function confirmPasswordReset(auth, oobCode, newPassword) {
|
|
|
22776
23231
|
await resetPassword(getModularInstance$1(auth), {
|
|
22777
23232
|
oobCode,
|
|
22778
23233
|
newPassword
|
|
23234
|
+
})
|
|
23235
|
+
.catch(async (error) => {
|
|
23236
|
+
if (error.code ===
|
|
23237
|
+
`auth/${"password-does-not-meet-requirements" /* AuthErrorCode.PASSWORD_DOES_NOT_MEET_REQUIREMENTS */}`) {
|
|
23238
|
+
void recachePasswordPolicy(auth);
|
|
23239
|
+
}
|
|
23240
|
+
throw error;
|
|
22779
23241
|
});
|
|
22780
23242
|
// Do not return the email.
|
|
22781
23243
|
}
|
|
@@ -22783,12 +23245,19 @@ async function confirmPasswordReset(auth, oobCode, newPassword) {
|
|
|
22783
23245
|
* Asynchronously signs in using an email and password.
|
|
22784
23246
|
*
|
|
22785
23247
|
* @remarks
|
|
22786
|
-
* Fails with an error if the email address and password do not match.
|
|
23248
|
+
* Fails with an error if the email address and password do not match. When
|
|
23249
|
+
* {@link https://cloud.google.com/identity-platform/docs/admin/email-enumeration-protection | Email Enumeration Protection}
|
|
23250
|
+
* is enabled, this method fails with "auth/invalid-credential" in case of an invalid
|
|
23251
|
+
* email/password.
|
|
23252
|
+
*
|
|
23253
|
+
* This method is not supported on {@link Auth} instances created with a
|
|
23254
|
+
* {@link @firebase/app#FirebaseServerApp}.
|
|
22787
23255
|
*
|
|
22788
23256
|
* Note: The user's password is NOT the password used to access the user's email account. The
|
|
22789
23257
|
* email address serves as a unique identifier for the user, and the password is used to access
|
|
22790
23258
|
* the user's account in your Firebase project. See also: {@link createUserWithEmailAndPassword}.
|
|
22791
23259
|
*
|
|
23260
|
+
*
|
|
22792
23261
|
* @param auth - The {@link Auth} instance.
|
|
22793
23262
|
* @param email - The users email address.
|
|
22794
23263
|
* @param password - The users password.
|
|
@@ -22796,7 +23265,15 @@ async function confirmPasswordReset(auth, oobCode, newPassword) {
|
|
|
22796
23265
|
* @public
|
|
22797
23266
|
*/
|
|
22798
23267
|
function signInWithEmailAndPassword(auth, email, password) {
|
|
22799
|
-
|
|
23268
|
+
if (_isFirebaseServerApp(auth.app)) {
|
|
23269
|
+
return Promise.reject(_serverAppCurrentUserOperationNotSupportedError(auth));
|
|
23270
|
+
}
|
|
23271
|
+
return signInWithCredential(getModularInstance$1(auth), EmailAuthProvider.credential(email, password)).catch(async (error) => {
|
|
23272
|
+
if (error.code === `auth/${"password-does-not-meet-requirements" /* AuthErrorCode.PASSWORD_DOES_NOT_MEET_REQUIREMENTS */}`) {
|
|
23273
|
+
void recachePasswordPolicy(auth);
|
|
23274
|
+
}
|
|
23275
|
+
throw error;
|
|
23276
|
+
});
|
|
22800
23277
|
}
|
|
22801
23278
|
/**
|
|
22802
23279
|
* Adds an observer for changes to the signed-in user's ID token.
|
|
@@ -22903,10 +23380,6 @@ class BrowserPersistenceClass {
|
|
|
22903
23380
|
* See the License for the specific language governing permissions and
|
|
22904
23381
|
* limitations under the License.
|
|
22905
23382
|
*/
|
|
22906
|
-
function _iframeCannotSyncWebStorage() {
|
|
22907
|
-
const ua = getUA();
|
|
22908
|
-
return _isSafari(ua) || _isIOS(ua);
|
|
22909
|
-
}
|
|
22910
23383
|
// The polling period in case events are not supported
|
|
22911
23384
|
const _POLLING_INTERVAL_MS$1 = 1000;
|
|
22912
23385
|
// The IE 10 localStorage cross tab synchronization delay in milliseconds
|
|
@@ -22920,8 +23393,6 @@ class BrowserLocalPersistence extends BrowserPersistenceClass {
|
|
|
22920
23393
|
// setTimeout return value is platform specific
|
|
22921
23394
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22922
23395
|
this.pollTimer = null;
|
|
22923
|
-
// Safari or iOS browser and embedded in an iframe.
|
|
22924
|
-
this.safariLocalStorageNotSynced = _iframeCannotSyncWebStorage() && _isIframe();
|
|
22925
23396
|
// Whether to use polling instead of depending on window events
|
|
22926
23397
|
this.fallbackToPolling = _isMobileBrowser();
|
|
22927
23398
|
this._shouldAllowMigration = true;
|
|
@@ -22960,27 +23431,6 @@ class BrowserLocalPersistence extends BrowserPersistenceClass {
|
|
|
22960
23431
|
// Remove polling listener to prevent possible event duplication.
|
|
22961
23432
|
this.stopPolling();
|
|
22962
23433
|
}
|
|
22963
|
-
// Safari embedded iframe. Storage event will trigger with the delta
|
|
22964
|
-
// changes but no changes will be applied to the iframe localStorage.
|
|
22965
|
-
if (this.safariLocalStorageNotSynced) {
|
|
22966
|
-
// Get current iframe page value.
|
|
22967
|
-
const storedValue = this.storage.getItem(key);
|
|
22968
|
-
// Value not synchronized, synchronize manually.
|
|
22969
|
-
if (event.newValue !== storedValue) {
|
|
22970
|
-
if (event.newValue !== null) {
|
|
22971
|
-
// Value changed from current value.
|
|
22972
|
-
this.storage.setItem(key, event.newValue);
|
|
22973
|
-
}
|
|
22974
|
-
else {
|
|
22975
|
-
// Current value deleted.
|
|
22976
|
-
this.storage.removeItem(key);
|
|
22977
|
-
}
|
|
22978
|
-
}
|
|
22979
|
-
else if (this.localCache[key] === event.newValue && !poll) {
|
|
22980
|
-
// Already detected and processed, do not trigger listeners again.
|
|
22981
|
-
return;
|
|
22982
|
-
}
|
|
22983
|
-
}
|
|
22984
23434
|
const triggerListeners = () => {
|
|
22985
23435
|
// Keep local map up to date in case storage event is triggered before
|
|
22986
23436
|
// poll.
|
|
@@ -23271,7 +23721,7 @@ class Receiver {
|
|
|
23271
23721
|
* Unsubscribe an event handler from a particular event.
|
|
23272
23722
|
*
|
|
23273
23723
|
* @param eventType - Event name to unsubscribe from.
|
|
23274
|
-
* @param eventHandler -
|
|
23724
|
+
* @param eventHandler - Optional event handler, if none provided, unsubscribe all handlers on this event.
|
|
23275
23725
|
*
|
|
23276
23726
|
*/
|
|
23277
23727
|
_unsubscribe(eventType, eventHandler) {
|
|
@@ -23765,11 +24215,13 @@ class IndexedDBLocalPersistence {
|
|
|
23765
24215
|
}
|
|
23766
24216
|
const keys = [];
|
|
23767
24217
|
const keysInResult = new Set();
|
|
23768
|
-
|
|
23769
|
-
|
|
23770
|
-
|
|
23771
|
-
this.
|
|
23772
|
-
|
|
24218
|
+
if (result.length !== 0) {
|
|
24219
|
+
for (const { fbase_key: key, value } of result) {
|
|
24220
|
+
keysInResult.add(key);
|
|
24221
|
+
if (JSON.stringify(this.localCache[key]) !== JSON.stringify(value)) {
|
|
24222
|
+
this.notifyListeners(key, value);
|
|
24223
|
+
keys.push(key);
|
|
24224
|
+
}
|
|
23773
24225
|
}
|
|
23774
24226
|
}
|
|
23775
24227
|
for (const localKey of Object.keys(this.localCache)) {
|
|
@@ -24225,6 +24677,9 @@ function pendingRedirectKey(auth) {
|
|
|
24225
24677
|
return _persistenceKeyName(PENDING_REDIRECT_KEY, auth.config.apiKey, auth.name);
|
|
24226
24678
|
}
|
|
24227
24679
|
async function _getRedirectResult(auth, resolverExtern, bypassAuthState = false) {
|
|
24680
|
+
if (_isFirebaseServerApp(auth.app)) {
|
|
24681
|
+
return Promise.reject(_serverAppCurrentUserOperationNotSupportedError(auth));
|
|
24682
|
+
}
|
|
24228
24683
|
const authInternal = _castAuth(auth);
|
|
24229
24684
|
const resolver = _withDefaultResolver(authInternal, resolverExtern);
|
|
24230
24685
|
const action = new RedirectAction(authInternal, resolver, bypassAuthState);
|
|
@@ -24455,7 +24910,7 @@ function matchDomain(expected) {
|
|
|
24455
24910
|
*/
|
|
24456
24911
|
const NETWORK_TIMEOUT = new Delay(30000, 60000);
|
|
24457
24912
|
/**
|
|
24458
|
-
* Reset
|
|
24913
|
+
* Reset unloaded GApi modules. If gapi.load fails due to a network error,
|
|
24459
24914
|
* it will stop working after a retrial. This is a hack to fix this issue.
|
|
24460
24915
|
*/
|
|
24461
24916
|
function resetUnloadedGapiModules() {
|
|
@@ -24535,7 +24990,7 @@ function loadGapi(auth) {
|
|
|
24535
24990
|
}
|
|
24536
24991
|
};
|
|
24537
24992
|
// Load GApi loader.
|
|
24538
|
-
return _loadJS(
|
|
24993
|
+
return _loadJS(`${_gapiScriptUrl()}?onload=${cbName}`)
|
|
24539
24994
|
.catch(e => reject(e));
|
|
24540
24995
|
}
|
|
24541
24996
|
}).catch(error => {
|
|
@@ -24790,7 +25245,7 @@ async function _getRedirectUrl(auth, provider, authType, redirectUrl, eventId, a
|
|
|
24790
25245
|
if (auth.tenantId) {
|
|
24791
25246
|
params.tid = auth.tenantId;
|
|
24792
25247
|
}
|
|
24793
|
-
// TODO: maybe set eid as
|
|
25248
|
+
// TODO: maybe set eid as endpointId
|
|
24794
25249
|
// TODO: maybe set fw as Frameworks.join(",")
|
|
24795
25250
|
const paramsDict = params;
|
|
24796
25251
|
for (const key of Object.keys(paramsDict)) {
|
|
@@ -24918,12 +25373,15 @@ class BrowserPopupRedirectResolver {
|
|
|
24918
25373
|
* An implementation of {@link PopupRedirectResolver} suitable for browser
|
|
24919
25374
|
* based applications.
|
|
24920
25375
|
*
|
|
25376
|
+
* @remarks
|
|
25377
|
+
* This method does not work in a Node.js environment.
|
|
25378
|
+
*
|
|
24921
25379
|
* @public
|
|
24922
25380
|
*/
|
|
24923
25381
|
const browserPopupRedirectResolver = BrowserPopupRedirectResolver;
|
|
24924
25382
|
|
|
24925
25383
|
var name = "@firebase/auth";
|
|
24926
|
-
var version = "
|
|
25384
|
+
var version = "1.7.7";
|
|
24927
25385
|
|
|
24928
25386
|
/**
|
|
24929
25387
|
* @license
|
|
@@ -25020,6 +25478,8 @@ function getVersionForPlatform(clientPlatform) {
|
|
|
25020
25478
|
return 'webworker';
|
|
25021
25479
|
case "Cordova" /* ClientPlatform.CORDOVA */:
|
|
25022
25480
|
return 'cordova';
|
|
25481
|
+
case "WebExtension" /* ClientPlatform.WEB_EXTENSION */:
|
|
25482
|
+
return 'web-extension';
|
|
25023
25483
|
default:
|
|
25024
25484
|
return undefined;
|
|
25025
25485
|
}
|
|
@@ -25129,11 +25589,18 @@ function getAuth(app = getApp()) {
|
|
|
25129
25589
|
browserSessionPersistence
|
|
25130
25590
|
]
|
|
25131
25591
|
});
|
|
25132
|
-
const
|
|
25133
|
-
|
|
25134
|
-
|
|
25135
|
-
|
|
25136
|
-
|
|
25592
|
+
const authTokenSyncPath = getExperimentalSetting('authTokenSyncURL');
|
|
25593
|
+
// Only do the Cookie exchange in a secure context
|
|
25594
|
+
if (authTokenSyncPath &&
|
|
25595
|
+
typeof isSecureContext === 'boolean' &&
|
|
25596
|
+
isSecureContext) {
|
|
25597
|
+
// Don't allow urls (XSS possibility), only paths on the same domain
|
|
25598
|
+
const authTokenSyncUrl = new URL(authTokenSyncPath, location.origin);
|
|
25599
|
+
if (location.origin === authTokenSyncUrl.origin) {
|
|
25600
|
+
const mintCookie = mintCookieFactory(authTokenSyncUrl.toString());
|
|
25601
|
+
beforeAuthStateChanged(auth, mintCookie, () => mintCookie(auth.currentUser));
|
|
25602
|
+
onIdTokenChanged(auth, user => mintCookie(user));
|
|
25603
|
+
}
|
|
25137
25604
|
}
|
|
25138
25605
|
const authEmulatorHost = getDefaultEmulatorHost$1('auth');
|
|
25139
25606
|
if (authEmulatorHost) {
|
|
@@ -25141,6 +25608,31 @@ function getAuth(app = getApp()) {
|
|
|
25141
25608
|
}
|
|
25142
25609
|
return auth;
|
|
25143
25610
|
}
|
|
25611
|
+
function getScriptParentElement() {
|
|
25612
|
+
var _a, _b;
|
|
25613
|
+
return (_b = (_a = document.getElementsByTagName('head')) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : document;
|
|
25614
|
+
}
|
|
25615
|
+
_setExternalJSProvider({
|
|
25616
|
+
loadJS(url) {
|
|
25617
|
+
// TODO: consider adding timeout support & cancellation
|
|
25618
|
+
return new Promise((resolve, reject) => {
|
|
25619
|
+
const el = document.createElement('script');
|
|
25620
|
+
el.setAttribute('src', url);
|
|
25621
|
+
el.onload = resolve;
|
|
25622
|
+
el.onerror = e => {
|
|
25623
|
+
const error = _createError("internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
|
|
25624
|
+
error.customData = e;
|
|
25625
|
+
reject(error);
|
|
25626
|
+
};
|
|
25627
|
+
el.type = 'text/javascript';
|
|
25628
|
+
el.charset = 'UTF-8';
|
|
25629
|
+
getScriptParentElement().appendChild(el);
|
|
25630
|
+
});
|
|
25631
|
+
},
|
|
25632
|
+
gapiScript: 'https://apis.google.com/js/api.js',
|
|
25633
|
+
recaptchaV2Script: 'https://www.google.com/recaptcha/api.js',
|
|
25634
|
+
recaptchaEnterpriseScript: 'https://www.google.com/recaptcha/enterprise.js?render='
|
|
25635
|
+
});
|
|
25144
25636
|
registerAuth("Browser" /* ClientPlatform.BROWSER */);
|
|
25145
25637
|
|
|
25146
25638
|
const fromFirebaseDate = (date) => {
|
|
@@ -25187,16 +25679,16 @@ class FirebaseUser {
|
|
|
25187
25679
|
var _a;
|
|
25188
25680
|
return (_a = this.user) === null || _a === void 0 ? void 0 : _a.uid;
|
|
25189
25681
|
}
|
|
25190
|
-
onInit(brandId) {
|
|
25191
|
-
|
|
25192
|
-
|
|
25193
|
-
|
|
25194
|
-
|
|
25195
|
-
unsub();
|
|
25196
|
-
if (user)
|
|
25197
|
-
this.logUserLogin(brandId, user);
|
|
25198
|
-
});
|
|
25682
|
+
async onInit(brandId) {
|
|
25683
|
+
this.auth.onAuthStateChanged((user) => {
|
|
25684
|
+
this.setUser(user);
|
|
25685
|
+
if (user)
|
|
25686
|
+
this.logUserLogin(brandId, user);
|
|
25199
25687
|
});
|
|
25688
|
+
await this.auth.authStateReady();
|
|
25689
|
+
const user = this.auth.currentUser;
|
|
25690
|
+
this.setUser(user);
|
|
25691
|
+
return Boolean(user);
|
|
25200
25692
|
}
|
|
25201
25693
|
setUser(user) {
|
|
25202
25694
|
this.user = user;
|